fix stream orientation
This commit is contained in:
parent
b0dace54d7
commit
82dae368e0
|
@ -8,7 +8,7 @@
|
||||||
<component name="DesignSurface">
|
<component name="DesignSurface">
|
||||||
<option name="filePathToZoomLevelMap">
|
<option name="filePathToZoomLevelMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="app/src/main/res/layout/stream.xml" value="0.1983695652173913" />
|
<entry key="../../../../../layout/custom_preview.xml" value="0.14448441247002397" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -53,7 +53,7 @@ class StreamActivity : AppCompatActivity() {
|
||||||
private var screenOrientation: Int = 0
|
private var screenOrientation: Int = 0
|
||||||
private var lastScreenOrientation: Int = 0
|
private var lastScreenOrientation: Int = 0
|
||||||
private var orientationCounter: Int = 0
|
private var orientationCounter: Int = 0
|
||||||
private var rotationIsLanternEnabled: Boolean = true
|
private var rotationIsEnabled: Boolean = true
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val BACKGROUND :Int = 1
|
const val BACKGROUND :Int = 1
|
||||||
|
@ -71,8 +71,9 @@ class StreamActivity : AppCompatActivity() {
|
||||||
|
|
||||||
orientationEventListener = object: OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL){
|
orientationEventListener = object: OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL){
|
||||||
override fun onOrientationChanged(orientation: Int) {
|
override fun onOrientationChanged(orientation: Int) {
|
||||||
if(orientation < 0 || !rotationIsLanternEnabled)
|
if(orientation < 0 || !rotationIsEnabled) {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
var localOrientation: Int
|
var localOrientation: Int
|
||||||
localOrientation = when (orientation) {
|
localOrientation = when (orientation) {
|
||||||
in 45..135 -> {
|
in 45..135 -> {
|
||||||
|
@ -108,6 +109,7 @@ class StreamActivity : AppCompatActivity() {
|
||||||
binding.flash.rotation = localOrientation.toFloat()
|
binding.flash.rotation = localOrientation.toFloat()
|
||||||
binding.muteMicro.rotation = localOrientation.toFloat()
|
binding.muteMicro.rotation = localOrientation.toFloat()
|
||||||
binding.switchCamera.rotation = localOrientation.toFloat()
|
binding.switchCamera.rotation = localOrientation.toFloat()
|
||||||
|
binding.rotation.rotation = localOrientation.toFloat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,12 +146,12 @@ class StreamActivity : AppCompatActivity() {
|
||||||
binding.flash.visibility = View.GONE
|
binding.flash.visibility = View.GONE
|
||||||
|
|
||||||
binding.rotation.setOnClickListener {
|
binding.rotation.setOnClickListener {
|
||||||
if (rotationIsLanternEnabled) {
|
if (rotationIsEnabled) {
|
||||||
rotationIsLanternEnabled = !rotationIsLanternEnabled
|
rotationIsEnabled = !rotationIsEnabled
|
||||||
binding.rotation.setImageResource(R.drawable.baseline_screen_lock_rotation_24)
|
binding.rotation.setImageResource(R.drawable.baseline_screen_lock_rotation_24)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rotationIsLanternEnabled = !rotationIsLanternEnabled
|
rotationIsEnabled = !rotationIsEnabled
|
||||||
binding.rotation.setImageResource(R.drawable.baseline_screen_rotation_24)
|
binding.rotation.setImageResource(R.drawable.baseline_screen_rotation_24)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,7 +353,8 @@ class StreamActivity : AppCompatActivity() {
|
||||||
|
|
||||||
//start stream
|
//start stream
|
||||||
|
|
||||||
if (rtmpCamera2.prepareAudio() && rtmpCamera2.prepareVideo(width,height,30, (width*height*30*0.076).toInt(),CameraHelper.getCameraOrientation(this))) {
|
if (rtmpCamera2.prepareAudio() && rtmpCamera2.prepareVideo(width,height,30, (width*height*30*0.076).toInt(),CameraHelper.getCameraOrientation(this),true)) {
|
||||||
|
println("peertubeurl "+streamData.url+"/"+streamData.key)
|
||||||
rtmpCamera2.startStream(streamData.url+"/"+streamData.key)
|
rtmpCamera2.startStream(streamData.url+"/"+streamData.key)
|
||||||
} else {
|
} else {
|
||||||
/**This device cant init encoders, this could be for 2 reasons: The encoder selected doesnt support any configuration setted or your device hasnt a H264 or AAC encoder (in this case you can see log error valid encoder not found) */
|
/**This device cant init encoders, this could be for 2 reasons: The encoder selected doesnt support any configuration setted or your device hasnt a H264 or AAC encoder (in this case you can see log error valid encoder not found) */
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class ScreenRender {
|
||||||
boolean flipStreamVertical, boolean flipStreamHorizontal) {
|
boolean flipStreamVertical, boolean flipStreamHorizontal) {
|
||||||
GlUtil.checkGlError("drawScreen start");
|
GlUtil.checkGlError("drawScreen start");
|
||||||
|
|
||||||
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
|
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical,width,height,true,keepAspectRatio, MVPMatrix);
|
||||||
SizeCalculator.calculateViewPort(keepAspectRatio, mode, width, height, streamWidth,
|
SizeCalculator.calculateViewPort(keepAspectRatio, mode, width, height, streamWidth,
|
||||||
streamHeight);
|
streamHeight);
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ public class ScreenRender {
|
||||||
boolean flipStreamVertical, boolean flipStreamHorizontal) {
|
boolean flipStreamVertical, boolean flipStreamHorizontal) {
|
||||||
GlUtil.checkGlError("drawScreen start");
|
GlUtil.checkGlError("drawScreen start");
|
||||||
|
|
||||||
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
|
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical,width, height, isPortrait,false, MVPMatrix);
|
||||||
SizeCalculator.calculateViewPortEncoder(width, height, isPortrait);
|
SizeCalculator.calculateViewPortEncoder(width, height, isPortrait);
|
||||||
|
|
||||||
draw(width, height);
|
draw(width, height);
|
||||||
|
@ -116,7 +116,7 @@ public class ScreenRender {
|
||||||
int mode, int rotation, boolean flipStreamVertical, boolean flipStreamHorizontal) {
|
int mode, int rotation, boolean flipStreamVertical, boolean flipStreamHorizontal) {
|
||||||
GlUtil.checkGlError("drawScreen start");
|
GlUtil.checkGlError("drawScreen start");
|
||||||
|
|
||||||
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
|
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, width, height, isPortrait,true, MVPMatrix);
|
||||||
float factor = (float) streamWidth / (float) streamHeight;
|
float factor = (float) streamWidth / (float) streamHeight;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class SimpleCameraRender {
|
||||||
GlUtil.checkGlError("drawFrame start");
|
GlUtil.checkGlError("drawFrame start");
|
||||||
surfaceTexture.getTransformMatrix(STMatrix);
|
surfaceTexture.getTransformMatrix(STMatrix);
|
||||||
|
|
||||||
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
|
SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, width, height, true, false, MVPMatrix);
|
||||||
SizeCalculator.calculateViewPort(keepAspectRatio, mode, width, height, streamWidth,
|
SizeCalculator.calculateViewPort(keepAspectRatio, mode, width, height, streamWidth,
|
||||||
streamHeight);
|
streamHeight);
|
||||||
|
|
||||||
|
|
|
@ -96,13 +96,14 @@ public class SizeCalculator {
|
||||||
}
|
}
|
||||||
return new Pair<>(new Point(xo, yo), new Point(xf, yf));
|
return new Pair<>(new Point(xo, yo), new Point(xf, yf));
|
||||||
} else {
|
} else {
|
||||||
return new Pair<>(new Point(0, 0), new Point(previewWidth, previewHeight));
|
//return new Pair<>(new Point(0, 0), new Point(previewWidth,previewHeight));
|
||||||
|
return new Pair<>(new Point(0, 0), new Point(previewHeight, previewWidth));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void processMatrix(int rotation, boolean flipStreamHorizontal,
|
public static void processMatrix(int rotation, boolean flipStreamHorizontal,
|
||||||
boolean flipStreamVertical, float[] MVPMatrix) {
|
boolean flipStreamVertical, int width, int height, boolean isPortrait, boolean isPreview, float[] MVPMatrix) {
|
||||||
PointF scale = new PointF(1f, 1f);
|
PointF scale = getScale(rotation,width,height, isPortrait, isPreview);
|
||||||
|
|
||||||
float xFlip = flipStreamHorizontal ? -1f : 1f;
|
float xFlip = flipStreamHorizontal ? -1f : 1f;
|
||||||
float yFlip = flipStreamVertical ? -1f : 1f;
|
float yFlip = flipStreamVertical ? -1f : 1f;
|
||||||
|
@ -117,18 +118,17 @@ public class SizeCalculator {
|
||||||
Matrix.rotateM(MVPMatrix, 0, rotation, 0f, 0f, -1f);
|
Matrix.rotateM(MVPMatrix, 0, rotation, 0f, 0f, -1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PointF getScale(int rotation, int width, int height, boolean isPortrait,
|
private static PointF getScale(int rotation, int width, int height, boolean isPortrait, boolean isPreview) {
|
||||||
boolean isPreview) {
|
|
||||||
float scaleX = 1f;
|
float scaleX = 1f;
|
||||||
float scaleY = 1f;
|
float scaleY = 1f;
|
||||||
if (!isPreview) {
|
if (!isPreview) {
|
||||||
if (isPortrait && rotation != 0 && rotation != 180) { //portrait
|
if (isPortrait && rotation != 90 && rotation != 270) { //portrait
|
||||||
final float adjustedWidth = width * (width / (float) height);
|
final float adjustedWidth = width * (width / (float) height);
|
||||||
scaleY = adjustedWidth / height;
|
scaleX = adjustedWidth / height;
|
||||||
} else if (!isPortrait && rotation != 90 && rotation != 270) { //landscape
|
} /*else if (isPortrait && rotation != 0 && rotation != 180) { //landscape
|
||||||
final float adjustedWidth = height * (height / (float) width);
|
final float adjustedWidth = height * (height / (float) width);
|
||||||
scaleX = adjustedWidth / width;
|
scaleY = adjustedWidth / width;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
return new PointF(scaleX, scaleY);
|
return new PointF(scaleX, scaleY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,20 @@ public class VideoEncoder extends BaseEncoder implements GetCameraData {
|
||||||
public boolean prepareVideoEncoder(int width, int height, int fps, int bitRate, int rotation,
|
public boolean prepareVideoEncoder(int width, int height, int fps, int bitRate, int rotation,
|
||||||
int iFrameInterval, FormatVideoEncoder formatVideoEncoder) {
|
int iFrameInterval, FormatVideoEncoder formatVideoEncoder) {
|
||||||
return prepareVideoEncoder(width, height, fps, bitRate, rotation, iFrameInterval,
|
return prepareVideoEncoder(width, height, fps, bitRate, rotation, iFrameInterval,
|
||||||
formatVideoEncoder, -1, -1);
|
formatVideoEncoder, -1, -1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean prepareVideoEncoder(int width, int height, int fps, int bitRate, int rotation,
|
||||||
|
int iFrameInterval, FormatVideoEncoder formatVideoEncoder, boolean landscape) {
|
||||||
|
return prepareVideoEncoder(width, height, fps, bitRate, rotation, iFrameInterval,
|
||||||
|
formatVideoEncoder, -1, -1, landscape);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean prepareVideoEncoder(int width, int height, int fps, int bitRate, int rotation,
|
||||||
|
int iFrameInterval, FormatVideoEncoder formatVideoEncoder, int avcProfile,
|
||||||
|
int avcProfileLevel) {
|
||||||
|
return prepareVideoEncoder(width, height, fps, bitRate, rotation, iFrameInterval,
|
||||||
|
formatVideoEncoder, avcProfile, avcProfileLevel, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +98,7 @@ public class VideoEncoder extends BaseEncoder implements GetCameraData {
|
||||||
*/
|
*/
|
||||||
public boolean prepareVideoEncoder(int width, int height, int fps, int bitRate, int rotation,
|
public boolean prepareVideoEncoder(int width, int height, int fps, int bitRate, int rotation,
|
||||||
int iFrameInterval, FormatVideoEncoder formatVideoEncoder, int avcProfile,
|
int iFrameInterval, FormatVideoEncoder formatVideoEncoder, int avcProfile,
|
||||||
int avcProfileLevel) {
|
int avcProfileLevel, boolean landscape) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.fps = fps;
|
this.fps = fps;
|
||||||
|
@ -116,10 +129,11 @@ public class VideoEncoder extends BaseEncoder implements GetCameraData {
|
||||||
//if you dont use mediacodec rotation you need swap width and height in rotation 90 or 270
|
//if you dont use mediacodec rotation you need swap width and height in rotation 90 or 270
|
||||||
// for correct encoding resolution
|
// for correct encoding resolution
|
||||||
String resolution;
|
String resolution;
|
||||||
if ((rotation == 90 || rotation == 270)) {
|
if (!landscape && (rotation == 90 || rotation == 270)) {
|
||||||
resolution = height + "x" + width;
|
resolution = height + "x" + width;
|
||||||
videoFormat = MediaFormat.createVideoFormat(type, height, width);
|
videoFormat = MediaFormat.createVideoFormat(type, height, width);
|
||||||
} else {
|
} else {
|
||||||
|
System.out.println("resolution "+width+"x"+height);
|
||||||
resolution = width + "x" + height;
|
resolution = width + "x" + height;
|
||||||
videoFormat = MediaFormat.createVideoFormat(type, width, height);
|
videoFormat = MediaFormat.createVideoFormat(type, width, height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,6 +318,7 @@ public abstract class Camera2Base implements GetAacData, GetVideoData, GetMicrop
|
||||||
stopPreview();
|
stopPreview();
|
||||||
onPreview = true;
|
onPreview = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean result = videoEncoder.prepareVideoEncoder(width, height, fps, bitrate, rotation,
|
boolean result = videoEncoder.prepareVideoEncoder(width, height, fps, bitrate, rotation,
|
||||||
iFrameInterval, FormatVideoEncoder.SURFACE, avcProfile, avcProfileLevel);
|
iFrameInterval, FormatVideoEncoder.SURFACE, avcProfile, avcProfileLevel);
|
||||||
prepareCameraManager();
|
prepareCameraManager();
|
||||||
|
@ -325,20 +326,34 @@ public abstract class Camera2Base implements GetAacData, GetVideoData, GetMicrop
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean prepareVideo(int width, int height, int fps, int bitrate, int iFrameInterval,
|
public boolean prepareVideo(int width, int height, int fps, int bitrate, int iFrameInterval,
|
||||||
int rotation) {
|
int rotation, int avcProfile, int avcProfileLevel, boolean landscape) {
|
||||||
return prepareVideo(width, height, fps, bitrate, iFrameInterval, rotation, -1, -1);
|
if (onPreview && glInterface != null && (width != previewWidth || height != previewHeight
|
||||||
|
|| fps != videoEncoder.getFps() || rotation != videoEncoder.getRotation())) {
|
||||||
|
stopPreview();
|
||||||
|
onPreview = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean result = videoEncoder.prepareVideoEncoder(width, height, fps, bitrate, rotation,
|
||||||
|
iFrameInterval, FormatVideoEncoder.SURFACE, avcProfile, avcProfileLevel,landscape);
|
||||||
|
prepareCameraManager();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean prepareVideo(int width, int height, int fps, int bitrate, int iFrameInterval,
|
||||||
|
int rotation, boolean landscape) {
|
||||||
|
return prepareVideo(width, height, fps, bitrate, iFrameInterval, rotation, -1, -1,landscape);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* backward compatibility reason
|
* backward compatibility reason
|
||||||
*/
|
*/
|
||||||
public boolean prepareVideo(int width, int height, int fps, int bitrate, int rotation) {
|
public boolean prepareVideo(int width, int height, int fps, int bitrate, int rotation, boolean landscape) {
|
||||||
return prepareVideo(width, height, fps, bitrate, 2, rotation);
|
return prepareVideo(width, height, fps, bitrate, 2, rotation,landscape);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean prepareVideo(int width, int height, int bitrate) {
|
public boolean prepareVideo(int width, int height, int bitrate) {
|
||||||
int rotation = CameraHelper.getCameraOrientation(context);
|
int rotation = CameraHelper.getCameraOrientation(context);
|
||||||
return prepareVideo(width, height, 30, bitrate, 2, rotation);
|
return prepareVideo(width, height, 30, bitrate, 2, rotation, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void prepareAudioRtp(boolean isStereo, int sampleRate);
|
protected abstract void prepareAudioRtp(boolean isStereo, int sampleRate);
|
||||||
|
@ -385,7 +400,7 @@ public abstract class Camera2Base implements GetAacData, GetVideoData, GetMicrop
|
||||||
*/
|
*/
|
||||||
public boolean prepareVideo() {
|
public boolean prepareVideo() {
|
||||||
int rotation = CameraHelper.getCameraOrientation(context);
|
int rotation = CameraHelper.getCameraOrientation(context);
|
||||||
return prepareVideo(640, 480, 30, 1200 * 1024, rotation);
|
return prepareVideo(640, 480, 30, 1200 * 1024, rotation,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue