OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |