Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Unified Diff: talk/app/webrtc/java/android/org/webrtc/RendererCommon.java

Issue 1318153007: Android video rendering: Apply SurfaceTexture.getTransformationMatrix() (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Change to updateLayoutMatrix() Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: talk/app/webrtc/java/android/org/webrtc/RendererCommon.java
diff --git a/talk/app/webrtc/java/android/org/webrtc/RendererCommon.java b/talk/app/webrtc/java/android/org/webrtc/RendererCommon.java
index 9f419da20312f45f59da0a322b43fb901e8ba52b..44b64151f5d30e9ef66dcdcde93aee5aa8698110 100644
--- a/talk/app/webrtc/java/android/org/webrtc/RendererCommon.java
+++ b/talk/app/webrtc/java/android/org/webrtc/RendererCommon.java
@@ -28,6 +28,7 @@
package org.webrtc;
import android.graphics.Point;
+import android.graphics.SurfaceTexture;
import android.opengl.Matrix;
/**
@@ -60,37 +61,62 @@ public class RendererCommon {
// The minimum fraction of the frame content that will be shown for |SCALE_ASPECT_BALANCED|.
// This limits excessive cropping when adjusting display size.
private static float BALANCED_VISIBLE_FRACTION = 0.5625f;
+ // Matrix with transform y' = 1 - y.
+ private static final float[] VERTICAL_FLIP = new float[] {
+ 1, 0, 0, 0,
+ 0, -1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 1, 0, 1};
/**
- * Calculates a texture transformation matrix based on rotation, mirror, and video vs display
- * aspect ratio.
+ * Returns matrix that transforms standard coordinates to their proper sampling locations in
+ * the texture. This transform compensates for any properties of the video source that
+ * cause it to appear different from a normalized texture. If the video source is based on
+ * ByteBuffers, pass null in |surfaceTexture|.
*/
- public static void getTextureMatrix(float[] outputTextureMatrix, float rotationDegree,
+ public static float[] getSamplingMatrix(SurfaceTexture surfaceTexture, float rotationDegree) {
+ final float[] samplingMatrix;
+ if (surfaceTexture == null) {
+ // For ByteBuffers, row 0 specifies the top row, but for a texture, row 0 specifies the
+ // bottom row. Flip the image vertically to compensate for this.
+ samplingMatrix = VERTICAL_FLIP;
+ } else {
+ samplingMatrix = new float[16];
+ surfaceTexture.getTransformMatrix(samplingMatrix);
+ }
+ // Clockwise rotation matrix in the XY-plane (around the Z-axis).
+ final float[] rotationMatrix = new float[16];
+ Matrix.setRotateM(rotationMatrix, 0, -rotationDegree, 0, 0, 1);
+ adjustOrigin(rotationMatrix);
+ // Multiply matrices together.
+ final float[] tmpMatrix = new float[16];
+ Matrix.multiplyMM(tmpMatrix, 0, rotationMatrix, 0, samplingMatrix, 0);
+ return tmpMatrix;
+ }
+
+ /**
+ * Returns layout transformation matrix that applies an optional mirror effect and compensates
+ * for video vs display aspect ratio.
+ */
+ public static float[] getLayoutMatrix(
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.
+ float scaleX = 1;
+ float scaleY = 1;
+ // Scale X or Y dimension so that video and display size have same aspect ratio.
if (displayAspectRatio > videoAspectRatio) {
- Matrix.scaleM(outputTextureMatrix, 0, 1, videoAspectRatio / displayAspectRatio, 1);
+ scaleY = videoAspectRatio / displayAspectRatio;
} else {
- Matrix.scaleM(outputTextureMatrix, 0, displayAspectRatio / videoAspectRatio, 1, 1);
+ scaleX = displayAspectRatio / videoAspectRatio;
}
- // 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);
+ scaleX *= -1;
}
- // Center coordinates around origin.
- Matrix.translateM(outputTextureMatrix, 0, -0.5f, -0.5f, 0.0f);
+ final float matrix[] = new float[16];
+ Matrix.setIdentityM(matrix, 0);
+ Matrix.scaleM(matrix, 0, scaleX, scaleY, 1);
+ adjustOrigin(matrix);
+ return matrix;
}
/**
@@ -103,6 +129,20 @@ public class RendererCommon {
}
/**
+ * Move |matrix| transformation origin to (0.5, 0.5). This is the origin for texture coordinates
+ * that are in the range 0 to 1.
+ */
+ private static void adjustOrigin(float[] matrix) {
+ // Note that OpenGL is using column-major order.
+ // Pre translate with -0.5 to move coordinates to range [-0.5, 0.5].
+ matrix[12] -= 0.5f * (matrix[0] + matrix[4]);
+ matrix[13] -= 0.5f * (matrix[1] + matrix[5]);
+ // Post translate with 0.5 to move coordinates to range [0, 1].
+ matrix[12] += 0.5f;
+ matrix[13] += 0.5f;
+ }
+
+ /**
* Each scaling type has a one-to-one correspondence to a numeric minimum fraction of the video
* that must remain visible.
*/

Powered by Google App Engine
This is Rietveld 408576698