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."); |
} |