Chromium Code Reviews| 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..239ea6e04efe8b8a1d64fe7f351f2ce154b6294f 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) { |
|
AlexG
2015/08/05 00:47:11
I think these helpers need to me moved to a separa
magjed_webrtc
2015/08/07 17:14:50
Done.
|
| + 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."); |
| } |
| @@ -431,6 +448,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
| // Skip rendering of this frame if setSize() was not called. |
| if (yuvFrameToRender == null || textureFrameToRender == null) { |
| framesDropped++; |
| + VideoRenderer.renderFrameDone(frame); |
| return; |
| } |
| // Check input frame parameters. |
| @@ -440,6 +458,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
| frame.yuvStrides[2] < frame.width / 2) { |
| Log.e(TAG, "Incorrect strides " + frame.yuvStrides[0] + ", " + |
| frame.yuvStrides[1] + ", " + frame.yuvStrides[2]); |
| + VideoRenderer.renderFrameDone(frame); |
| return; |
| } |
| // Check incoming frame dimensions. |
| @@ -453,6 +472,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
| if (frameToRenderQueue.size() > 0) { |
| // Skip rendering of this frame if previous frame was not rendered yet. |
| framesDropped++; |
| + VideoRenderer.renderFrameDone(frame); |
| return; |
| } |
| @@ -468,6 +488,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
| } |
| copyTimeNs += (System.nanoTime() - now); |
| seenFrame = true; |
| + VideoRenderer.renderFrameDone(frame); |
| // Request rendering. |
| surface.requestRender(); |