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

Side by Side 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: 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 10 matching lines...) Expand all
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 package org.webrtc; 28 package org.webrtc;
29 29
30 import android.graphics.Point; 30 import android.graphics.Point;
31 import android.graphics.SurfaceTexture;
31 import android.opengl.Matrix; 32 import android.opengl.Matrix;
32 33
33 /** 34 /**
34 * Static helper functions for renderer implementations. 35 * Static helper functions for renderer implementations.
35 */ 36 */
36 public class RendererCommon { 37 public class RendererCommon {
37 /** Interface for reporting rendering events. */ 38 /** Interface for reporting rendering events. */
38 public static interface RendererEvents { 39 public static interface RendererEvents {
39 /** 40 /**
40 * Callback fired once first frame is rendered. 41 * Callback fired once first frame is rendered.
(...skipping 12 matching lines...) Expand all
53 // SCALE_ASPECT_FILL - video frame is scaled to fill the size of the view by 54 // SCALE_ASPECT_FILL - video frame is scaled to fill the size of the view by
54 // maintaining the aspect ratio. Some portion of the video frame may be 55 // maintaining the aspect ratio. Some portion of the video frame may be
55 // clipped. 56 // clipped.
56 // SCALE_ASPECT_BALANCED - Compromise between FIT and FILL. Video frame will f ill as much as 57 // SCALE_ASPECT_BALANCED - Compromise between FIT and FILL. Video frame will f ill as much as
57 // possible of the view while maintaining aspect ratio, under the constraint t hat at least 58 // possible of the view while maintaining aspect ratio, under the constraint t hat at least
58 // |BALANCED_VISIBLE_FRACTION| of the frame content will be shown. 59 // |BALANCED_VISIBLE_FRACTION| of the frame content will be shown.
59 public static enum ScalingType { SCALE_ASPECT_FIT, SCALE_ASPECT_FILL, SCALE_AS PECT_BALANCED } 60 public static enum ScalingType { SCALE_ASPECT_FIT, SCALE_ASPECT_FILL, SCALE_AS PECT_BALANCED }
60 // The minimum fraction of the frame content that will be shown for |SCALE_ASP ECT_BALANCED|. 61 // The minimum fraction of the frame content that will be shown for |SCALE_ASP ECT_BALANCED|.
61 // This limits excessive cropping when adjusting display size. 62 // This limits excessive cropping when adjusting display size.
62 private static float BALANCED_VISIBLE_FRACTION = 0.5625f; 63 private static float BALANCED_VISIBLE_FRACTION = 0.5625f;
64 // Matrix with transform y' = 1 - y.
65 private static float[] VERTICAL_FLIP = new float[] {
66 1, 0, 0, 0,
67 0, -1, 0, 0,
68 0, 0, 1, 0,
69 0, 1, 0, 1};
hbos 2015/09/08 14:08:47 nit: Could make this final (even though it wouldn'
magjed_webrtc 2015/09/08 15:24:28 Done.
63 70
64 /** 71 /**
65 * Calculates a texture transformation matrix based on rotation, mirror, and v ideo vs display 72 * Returns matrix that transforms standard coordinates to their proper samplin g locations in
66 * aspect ratio. 73 * the texture. This transform compensates for any properties of the video sou rce that
74 * cause it to appear different from a normalized texture. If the video source is based on
75 * ByteBuffers, pass null in |surfaceTexture|.
67 */ 76 */
68 public static void getTextureMatrix(float[] outputTextureMatrix, float rotatio nDegree, 77 public static float[] getSamplingMatrix(SurfaceTexture surfaceTexture, float r otationDegree) {
69 boolean mirror, float videoAspectRatio, float displayAspectRatio) { 78 final float[] samplingMatrix;
70 // The matrix stack is using post-multiplication, which means that matrix op erations: 79 if (surfaceTexture == null) {
71 // A; B; C; will end up as A * B * C. When you apply this to a vertex, it wi ll result in: 80 // For ByteBuffers, row 0 specifies the top row, but for a texture, row 0 specifies the
72 // v' = A * B * C * v, i.e. the last matrix operation is the first thing tha t affects the 81 // bottom row. Flip the image vertically to compensate for this.
73 // vertex. This is the opposite of what you might expect. 82 samplingMatrix = VERTICAL_FLIP;
74 Matrix.setIdentityM(outputTextureMatrix, 0);
75 // Move coordinates back to [0,1]x[0,1].
76 Matrix.translateM(outputTextureMatrix, 0, 0.5f, 0.5f, 0.0f);
77 // Rotate frame clockwise in the XY-plane (around the Z-axis).
78 Matrix.rotateM(outputTextureMatrix, 0, -rotationDegree, 0, 0, 1);
79 // Scale one dimension until video and display size have same aspect ratio.
80 if (displayAspectRatio > videoAspectRatio) {
81 Matrix.scaleM(outputTextureMatrix, 0, 1, videoAspectRatio / displayAspectR atio, 1);
82 } else { 83 } else {
83 Matrix.scaleM(outputTextureMatrix, 0, displayAspectRatio / videoAspectRati o, 1, 1); 84 samplingMatrix = new float[16];
85 surfaceTexture.getTransformMatrix(samplingMatrix);
84 } 86 }
85 // TODO(magjed): We currently ignore the texture transform matrix from the S urfaceTexture. 87 // Clockwise rotation matrix in the XY-plane (around the Z-axis).
86 // It contains a vertical flip that is hardcoded here instead. 88 final float[] rotationMatrix = new float[16];
87 Matrix.scaleM(outputTextureMatrix, 0, 1, -1, 1); 89 Matrix.setRotateM(rotationMatrix, 0, -rotationDegree, 0, 0, 1);
88 // Apply optional horizontal flip. 90 adjustOrigin(rotationMatrix);
89 if (mirror) { 91 // Multiply matrices together.
90 Matrix.scaleM(outputTextureMatrix, 0, -1, 1, 1); 92 final float[] tmpMatrix = new float[16];
91 } 93 Matrix.multiplyMM(tmpMatrix, 0, rotationMatrix, 0, samplingMatrix, 0);
92 // Center coordinates around origin. 94 return tmpMatrix;
93 Matrix.translateM(outputTextureMatrix, 0, -0.5f, -0.5f, 0.0f);
94 } 95 }
95 96
96 /** 97 /**
98 * Returns layout transformation matrix that applies an optional mirror effect and compensates
99 * for video vs display aspect ratio.
100 */
101 public static float[] getLayoutMatrix(
102 boolean mirror, float videoAspectRatio, float displayAspectRatio) {
103 float scaleX = 1;
104 float scaleY = 1;
105 // Scale X or Y dimension so that video and display size have same aspect ra tio.
106 if (displayAspectRatio > videoAspectRatio) {
107 scaleY = videoAspectRatio / displayAspectRatio;
108 } else {
109 scaleX = displayAspectRatio / videoAspectRatio;
110 }
111 // Apply optional horizontal flip.
112 if (mirror) {
113 scaleX *= -1;
114 }
115 final float matrix[] = new float[16];
116 Matrix.setIdentityM(matrix, 0);
117 Matrix.scaleM(matrix, 0, scaleX, scaleY, 1);
118 adjustOrigin(matrix);
hbos 2015/09/08 14:08:47 Does "adjustOrigin" have any effect on a scale mat
magjed_webrtc 2015/09/08 15:24:28 Yes. Otherwise it will zoom in/out around the corn
hbos 2015/09/09 08:27:54 Acknowledged.
119 return matrix;
120 }
121
122 /**
97 * Calculate display size based on scaling type, video aspect ratio, and maxim um display size. 123 * Calculate display size based on scaling type, video aspect ratio, and maxim um display size.
98 */ 124 */
99 public static Point getDisplaySize(ScalingType scalingType, float videoAspectR atio, 125 public static Point getDisplaySize(ScalingType scalingType, float videoAspectR atio,
100 int maxDisplayWidth, int maxDisplayHeight) { 126 int maxDisplayWidth, int maxDisplayHeight) {
101 return getDisplaySize(convertScalingTypeToVisibleFraction(scalingType), vide oAspectRatio, 127 return getDisplaySize(convertScalingTypeToVisibleFraction(scalingType), vide oAspectRatio,
102 maxDisplayWidth, maxDisplayHeight); 128 maxDisplayWidth, maxDisplayHeight);
103 } 129 }
104 130
105 /** 131 /**
132 * Move |matrix| transformation origin to (0.5, 0.5). This is the origin for t exture coordinates
133 * that are in the range 0 to 1.
134 */
135 private static void adjustOrigin(float[] matrix) {
136 // Note that OpenGL is using column-major order.
137 // Pre translate with -0.5 to move coordinates to range [-0.5, 0.5].
138 matrix[12] -= 0.5f * (matrix[0] + matrix[4]);
139 matrix[13] -= 0.5f * (matrix[1] + matrix[5]);
140 // Post translate with 0.5 to move coordinates to range [0, 1].
141 matrix[12] += 0.5f;
142 matrix[13] += 0.5f;
143 }
hbos 2015/09/08 14:08:47 What assumptions, if any, about |matrix| enable th
magjed_webrtc 2015/09/08 15:24:28 No assumptions really, this is just two inlined an
hbos 2015/09/09 08:27:54 Acknowledged.
144
145 /**
106 * Each scaling type has a one-to-one correspondence to a numeric minimum frac tion of the video 146 * Each scaling type has a one-to-one correspondence to a numeric minimum frac tion of the video
107 * that must remain visible. 147 * that must remain visible.
108 */ 148 */
109 private static float convertScalingTypeToVisibleFraction(ScalingType scalingTy pe) { 149 private static float convertScalingTypeToVisibleFraction(ScalingType scalingTy pe) {
110 switch (scalingType) { 150 switch (scalingType) {
111 case SCALE_ASPECT_FIT: 151 case SCALE_ASPECT_FIT:
112 return 1.0f; 152 return 1.0f;
113 case SCALE_ASPECT_FILL: 153 case SCALE_ASPECT_FILL:
114 return 0.0f; 154 return 0.0f;
115 case SCALE_ASPECT_BALANCED: 155 case SCALE_ASPECT_BALANCED:
(...skipping 14 matching lines...) Expand all
130 return new Point(maxDisplayWidth, maxDisplayHeight); 170 return new Point(maxDisplayWidth, maxDisplayHeight);
131 } 171 }
132 // Each dimension is constrained on max display size and how much we are all owed to crop. 172 // Each dimension is constrained on max display size and how much we are all owed to crop.
133 final int width = Math.min(maxDisplayWidth, 173 final int width = Math.min(maxDisplayWidth,
134 (int) (maxDisplayHeight / minVisibleFraction * videoAspectRatio)); 174 (int) (maxDisplayHeight / minVisibleFraction * videoAspectRatio));
135 final int height = Math.min(maxDisplayHeight, 175 final int height = Math.min(maxDisplayHeight,
136 (int) (maxDisplayWidth / minVisibleFraction / videoAspectRatio)); 176 (int) (maxDisplayWidth / minVisibleFraction / videoAspectRatio));
137 return new Point(width, height); 177 return new Point(width, height);
138 } 178 }
139 } 179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698