fix stream orientation

This commit is contained in:
Schoumi 2022-07-14 13:33:30 +02:00
parent b0dace54d7
commit 82dae368e0
7 changed files with 62 additions and 30 deletions

View File

@ -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>

View File

@ -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) */

View File

@ -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;

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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);
} }
/** /**