| Index: talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| diff --git a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| index 0c910f14c7b4a51456d4ed98cd8ec53b2e3fa570..293150d5f37d10481e9610192bf344d2b5c1cb07 100644
|
| --- a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| +++ b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| @@ -102,6 +102,73 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| }
|
|
|
| /**
|
| + * Each scaling type has a one-to-one correspondence to a numeric minimum fraction of the video
|
| + * that must remain visible.
|
| + */
|
| + public static float convertScalingTypeToVisibleFraction(ScalingType scalingType) {
|
| + switch (scalingType) {
|
| + case SCALE_ASPECT_FIT:
|
| + return 1.0f;
|
| + case SCALE_ASPECT_FILL:
|
| + return 0.0f;
|
| + case SCALE_ASPECT_BALANCED:
|
| + return BALANCED_VISIBLE_FRACTION;
|
| + default:
|
| + throw new IllegalArgumentException();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Calculates display size based on minimum fraction of the video that must remain visible,
|
| + * video aspect ratio, and maximum display size.
|
| + */
|
| + public static Point getDisplaySize(float minVisibleFraction, float videoAspectRatio,
|
| + int maxDisplayWidth, int maxDisplayHeight) {
|
| + // If there is no constraint on the amount of cropping, fill the allowed display area.
|
| + if (minVisibleFraction == 0 || videoAspectRatio == 0) {
|
| + return new Point(maxDisplayWidth, maxDisplayHeight);
|
| + }
|
| + // Each dimension is constrained on max display size and how much we are allowed to crop.
|
| + final int width = Math.min(maxDisplayWidth,
|
| + (int) (maxDisplayHeight / minVisibleFraction * videoAspectRatio));
|
| + final int height = Math.min(maxDisplayHeight,
|
| + (int) (maxDisplayWidth / minVisibleFraction / videoAspectRatio));
|
| + return new Point(width, height);
|
| + }
|
| +
|
| + /**
|
| + * Calculates a texture transformation matrix based on rotation, mirror, and video vs display
|
| + * aspect ratio.
|
| + */
|
| + public static void getTextureMatrix(float[] outputTextureMatrix, float rotationDegree,
|
| + boolean mirror, float videoAspectRatio, float displayAspectRatio) {
|
| + // The matrix stack is using post-multiplication, which means that matrix operations:
|
| + // A; B; C; will end up as A * B * C. When you apply this to a vertex, it will result in:
|
| + // v' = A * B * C * v, i.e. the last matrix operation is the first thing that affects the
|
| + // vertex. This is the opposite of what you might expect.
|
| + Matrix.setIdentityM(outputTextureMatrix, 0);
|
| + // Move coordinates back to [0,1]x[0,1].
|
| + Matrix.translateM(outputTextureMatrix, 0, 0.5f, 0.5f, 0.0f);
|
| + // Rotate frame clockwise in the XY-plane (around the Z-axis).
|
| + Matrix.rotateM(outputTextureMatrix, 0, -rotationDegree, 0, 0, 1);
|
| + // Scale one dimension until video and display size have same aspect ratio.
|
| + if (displayAspectRatio > videoAspectRatio) {
|
| + Matrix.scaleM(outputTextureMatrix, 0, 1, videoAspectRatio / displayAspectRatio, 1);
|
| + } else {
|
| + Matrix.scaleM(outputTextureMatrix, 0, displayAspectRatio / videoAspectRatio, 1, 1);
|
| + }
|
| + // TODO(magjed): We currently ignore the texture transform matrix from the SurfaceTexture.
|
| + // It contains a vertical flip that is hardcoded here instead.
|
| + Matrix.scaleM(outputTextureMatrix, 0, 1, -1, 1);
|
| + // Apply optional horizontal flip.
|
| + if (mirror) {
|
| + Matrix.scaleM(outputTextureMatrix, 0, -1, 1, 1);
|
| + }
|
| + // Center coordinates around origin.
|
| + Matrix.translateM(outputTextureMatrix, 0, -0.5f, -0.5f, 0.0f);
|
| + }
|
| +
|
| + /**
|
| * Class used to display stream of YUV420 frames at particular location
|
| * on a screen. New video frames are sent to display using renderFrame()
|
| * call.
|
| @@ -199,33 +266,6 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| GlUtil.checkNoGLES2Error("y/u/v glGenTextures");
|
| }
|
|
|
| - private static float convertScalingTypeToVisibleFraction(ScalingType scalingType) {
|
| - switch (scalingType) {
|
| - case SCALE_ASPECT_FIT:
|
| - return 1.0f;
|
| - case SCALE_ASPECT_FILL:
|
| - return 0.0f;
|
| - case SCALE_ASPECT_BALANCED:
|
| - return BALANCED_VISIBLE_FRACTION;
|
| - default:
|
| - throw new IllegalArgumentException();
|
| - }
|
| - }
|
| -
|
| - private static Point getDisplaySize(float minVisibleFraction, float videoAspectRatio,
|
| - int maxDisplayWidth, int maxDisplayHeight) {
|
| - // If there is no constraint on the amount of cropping, fill the allowed display area.
|
| - if (minVisibleFraction == 0) {
|
| - return new Point(maxDisplayWidth, maxDisplayHeight);
|
| - }
|
| - // Each dimension is constrained on max display size and how much we are allowed to crop.
|
| - final int width = Math.min(maxDisplayWidth,
|
| - (int) (maxDisplayHeight / minVisibleFraction * videoAspectRatio));
|
| - final int height = Math.min(maxDisplayHeight,
|
| - (int) (maxDisplayWidth / minVisibleFraction / videoAspectRatio));
|
| - return new Point(width, height);
|
| - }
|
| -
|
| private void checkAdjustTextureCoords() {
|
| synchronized(updateTextureLock) {
|
| if (!updateTextureProperties) {
|
| @@ -252,31 +292,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| (displayLayout.height() - displaySize.y) / 2);
|
| Log.d(TAG, " Adjusted display size: " + displayLayout.width() + " x "
|
| + displayLayout.height());
|
| - // The matrix stack is using post-multiplication, which means that matrix operations:
|
| - // A; B; C; will end up as A * B * C. When you apply this to a vertex, it will result in:
|
| - // v' = A * B * C * v, i.e. the last matrix operation is the first thing that affects the
|
| - // vertex. This is the opposite of what you might expect.
|
| - Matrix.setIdentityM(texMatrix, 0);
|
| - // Move coordinates back to [0,1]x[0,1].
|
| - Matrix.translateM(texMatrix, 0, 0.5f, 0.5f, 0.0f);
|
| - // Rotate frame clockwise in the XY-plane (around the Z-axis).
|
| - Matrix.rotateM(texMatrix, 0, -rotationDegree, 0, 0, 1);
|
| - // Scale one dimension until video and display size have same aspect ratio.
|
| - final float displayAspectRatio = (float) displayLayout.width() / displayLayout.height();
|
| - if (displayAspectRatio > videoAspectRatio) {
|
| - Matrix.scaleM(texMatrix, 0, 1, videoAspectRatio / displayAspectRatio, 1);
|
| - } else {
|
| - Matrix.scaleM(texMatrix, 0, displayAspectRatio / videoAspectRatio, 1, 1);
|
| - }
|
| - // TODO(magjed): We currently ignore the texture transform matrix from the SurfaceTexture.
|
| - // It contains a vertical flip that is hardcoded here instead.
|
| - Matrix.scaleM(texMatrix, 0, 1, -1, 1);
|
| - // Apply optional horizontal flip.
|
| - if (mirror) {
|
| - Matrix.scaleM(texMatrix, 0, -1, 1, 1);
|
| - }
|
| - // Center coordinates around origin.
|
| - Matrix.translateM(texMatrix, 0, -0.5f, -0.5f, 0.0f);
|
| + getTextureMatrix(texMatrix, rotationDegree, mirror, videoAspectRatio,
|
| + (float) displayLayout.width() / displayLayout.height());
|
| updateTextureProperties = false;
|
| Log.d(TAG, " AdjustTextureCoords done");
|
| }
|
| @@ -415,9 +432,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| frameToRenderQueue.poll();
|
| // Re-allocate / allocate the frame.
|
| yuvFrameToRender = new I420Frame(videoWidth, videoHeight, rotationDegree,
|
| - strides, null);
|
| + strides, null, 0);
|
| textureFrameToRender = new I420Frame(videoWidth, videoHeight, rotationDegree,
|
| - null, -1);
|
| + null, -1, 0);
|
| updateTextureProperties = true;
|
| Log.d(TAG, " YuvImageRenderer.setSize done.");
|
| }
|
|
|