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

Side by Side Diff: talk/app/webrtc/androidtests/src/org/webrtc/SurfaceViewRendererOnMeasureTest.java

Issue 1379793003: Android SurfaceViewRenderer: Add tests for onMeasure() (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « no previous file | talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2015 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
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,
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
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 package org.webrtc;
29
30 import android.opengl.EGL14;
31 import android.test.ActivityTestCase;
32 import android.test.suitebuilder.annotation.MediumTest;
33 import android.view.View.MeasureSpec;
34
35 import java.nio.ByteBuffer;
36 import java.util.Arrays;
37 import java.util.List;
38
39 public final class SurfaceViewRendererOnMeasureTest extends ActivityTestCase {
40 /**
41 * List with all possible scaling types.
42 */
43 private static final List<RendererCommon.ScalingType> scalingTypes = Arrays.as List(
44 RendererCommon.ScalingType.SCALE_ASPECT_FIT,
45 RendererCommon.ScalingType.SCALE_ASPECT_FILL,
46 RendererCommon.ScalingType.SCALE_ASPECT_BALANCED);
47
48 /**
49 * List with MeasureSpec modes.
50 */
51 private static final List<Integer> measureSpecModes =
52 Arrays.asList(MeasureSpec.EXACTLY, MeasureSpec.AT_MOST);
hbos 2015/10/06 08:15:16 In the below tests, why do we expect the AT_MOST m
magjed_webrtc 2015/10/07 08:43:52 After a frame is delivered we know exactly how big
hbos 2015/10/07 09:47:09 Acknowledged.
53
54 /**
55 * Returns a dummy YUV frame.
56 */
57 static VideoRenderer.I420Frame createFrame(int width, int height, int rotation Degree) {
58 final int[] yuvStrides = new int[] {width, (width + 1) / 2, (width + 1) / 2} ;
59 final int[] yuvHeights = new int[] {height, (height + 1) / 2, (height + 1) / 2};
60 final ByteBuffer[] yuvPlanes = new ByteBuffer[3];
61 for (int i = 0; i < 3; ++i) {
62 yuvPlanes[i] = ByteBuffer.allocateDirect(yuvStrides[i] * yuvHeights[i]);
63 }
64 return new VideoRenderer.I420Frame(width, height, rotationDegree, yuvStrides , yuvPlanes, 0);
65 }
hbos 2015/10/06 08:15:16 Remember multiple of 16 stride alignments and Vide
magjed_webrtc 2015/10/07 08:43:53 Yeah, that's specific to the camera. We can use wh
hbos 2015/10/07 09:47:09 Acknowledged.
66
67 /**
68 * Assert onMeasure() with given parameters will result in expected measured s ize.
69 */
70 private static void assertMeasuredSize(
71 SurfaceViewRenderer surfaceViewRenderer, RendererCommon.ScalingType scalin gType,
72 String frameDimensions,
73 int expectedWidth, int expectedHeight,
74 int widthSpec, int heightSpec) {
75 surfaceViewRenderer.setScalingType(scalingType);
76 surfaceViewRenderer.onMeasure(widthSpec, heightSpec);
hbos 2015/10/06 08:15:16 I looked at onMeasure. The way it obtains and rele
magjed_webrtc 2015/10/07 08:43:52 Hmm. onMeasure() is only called from UI thread in
hbos 2015/10/07 09:47:09 Acknowledged.
77 final int measuredWidth = surfaceViewRenderer.getMeasuredWidth();
78 final int measuredHeight = surfaceViewRenderer.getMeasuredHeight();
79 if (measuredWidth != expectedWidth || measuredHeight != expectedHeight) {
80 fail("onMeasure("
81 + MeasureSpec.toString(widthSpec) + ", " + MeasureSpec.toString(height Spec) + ")"
82 + " with scaling type " + scalingType
83 + " and frame: " + frameDimensions
84 + " expected measured size " + expectedWidth + "x" + expectedHeight
85 + ", but was " + measuredWidth + "x" + measuredHeight);
86 }
87 }
88
89 /**
90 * Test how SurfaceViewRenderer.onMeasure() behaves when no frame has been del ivered.
91 */
92 @MediumTest
93 public void testNoFrame() {
94 final SurfaceViewRenderer surfaceViewRenderer =
95 new SurfaceViewRenderer(getInstrumentation().getContext());
96 final String frameDimensions = "null";
97
98 // Test behaviour before SurfaceViewRenderer.init() is called.
99 for (RendererCommon.ScalingType scalingType : scalingTypes) {
100 for (int measureSpecMode : measureSpecModes) {
101 final int zeroMeasureSize = MeasureSpec.makeMeasureSpec(0, measureSpecMo de);
102 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
103 0, 0, zeroMeasureSize, zeroMeasureSize);
104 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
105 1280, 720,
106 MeasureSpec.makeMeasureSpec(1280, measureSpecMode),
107 MeasureSpec.makeMeasureSpec(720, measureSpecMode));
108 }
109 }
110
111 // Test behaviour after SurfaceViewRenderer.init() is called, but still no fr ame.
112 surfaceViewRenderer.init(EGL14.EGL_NO_CONTEXT, null);
113 for (RendererCommon.ScalingType scalingType : scalingTypes) {
114 for (int measureSpecMode : measureSpecModes) {
115 final int zeroMeasureSize = MeasureSpec.makeMeasureSpec(0, measureSpecMo de);
116 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
117 0, 0, zeroMeasureSize, zeroMeasureSize);
118 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
119 1280, 720,
120 MeasureSpec.makeMeasureSpec(1280, measureSpecMode),
121 MeasureSpec.makeMeasureSpec(720, measureSpecMode));
122 }
123 }
124
125 surfaceViewRenderer.release();
126 }
127
128 /**
129 * Test how SurfaceViewRenderer.onMeasure() behaves with a 1280x720 frame.
130 */
131 @MediumTest
132 public void testFrame1280x720() {
133 final SurfaceViewRenderer surfaceViewRenderer =
134 new SurfaceViewRenderer(getInstrumentation().getContext());
135 surfaceViewRenderer.init(EGL14.EGL_NO_CONTEXT, null);
136
137 // Test different rotation degress, but same rotated size.
138 for (int rotationDegree : new int[] {0, 90, 180, 270}) {
139 final int rotatedWidth = 1280;
140 final int rotatedHeight = 720;
141 final int unrotatedWidth = (rotationDegree % 180 == 0 ? rotatedWidth : rot atedHeight);
142 final int unrotatedHeight = (rotationDegree % 180 == 0 ? rotatedHeight : r otatedWidth);
143 final VideoRenderer.I420Frame frame =
144 createFrame(unrotatedWidth, unrotatedHeight, rotationDegree);
145 assertEquals(rotatedWidth, frame.rotatedWidth());
146 assertEquals(rotatedHeight, frame.rotatedHeight());
147 final String frameDimensions =
148 unrotatedWidth + "x" + unrotatedHeight + " with rotation " + rotationD egree;
149 surfaceViewRenderer.renderFrame(frame);
150
151 // Test forcing to zero size.
152 for (RendererCommon.ScalingType scalingType : scalingTypes) {
153 for (int measureSpecMode : measureSpecModes) {
154 final int zeroMeasureSize = MeasureSpec.makeMeasureSpec(0, measureSpec Mode);
155 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
156 0, 0, zeroMeasureSize, zeroMeasureSize);
157 }
158 }
159
160 // Test perfect fit.
161 for (RendererCommon.ScalingType scalingType : scalingTypes) {
162 for (int measureSpecMode : measureSpecModes) {
163 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
164 rotatedWidth, rotatedHeight,
165 MeasureSpec.makeMeasureSpec(rotatedWidth, measureSpecMode),
166 MeasureSpec.makeMeasureSpec(rotatedHeight, measureSpecMode));
167 }
168 }
169
170 // Force spec size with different aspect ratio than frame aspect ratio.
171 for (RendererCommon.ScalingType scalingType : scalingTypes) {
172 assertMeasuredSize(surfaceViewRenderer, scalingType, frameDimensions,
173 720, 1280,
174 MeasureSpec.makeMeasureSpec(720, MeasureSpec.EXACTLY),
175 MeasureSpec.makeMeasureSpec(1280, MeasureSpec.EXACTLY));
176 }
177
178 // Note about expected sizes:
179 // * SCALE_ASPECT_FIT will try to show the whole frame, which means keepin g the same
180 // layout aspect ratio as the frame. For a 1280x720 frame (16:9) and at most 720 spec
181 // width, this means a layout size of 720x405 (16:9).
182 // * SCALE_ASPECT_FILL will simply maximize the layout size given the meas ure constraints.
183 // * SCALE_ASPECT_BALANCED allows showing only a part of the frame. The la yout size will be
184 // 720x720 because 720x720 / 1280x720 = 9/16 = RendererCommon.BALANCED_V ISIBLE_FRACTION.
185 {
186 // Relax both width and height constraints.
187 final int widthSpec = MeasureSpec.makeMeasureSpec(720, MeasureSpec.AT_MO ST);
188 final int heightSpec = MeasureSpec.makeMeasureSpec(1280, MeasureSpec.AT_ MOST);
189 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_FIT,
190 frameDimensions, 720, 405, widthSpec, heightSpec);
191 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_FILL,
192 frameDimensions, 720, 1280, widthSpec, heightSpec);
193 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_BALANCED,
194 frameDimensions, 720, 720, widthSpec, heightSpec);
195 }
196 {
197 // Force width to 720, but relax height constraint. This will give the s ame result as above.
198 final int widthSpec = MeasureSpec.makeMeasureSpec(720, MeasureSpec.EXACT LY);
199 final int heightSpec = MeasureSpec.makeMeasureSpec(1280, MeasureSpec.AT_ MOST);
200 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_FIT,
201 frameDimensions, 720, 405, widthSpec, heightSpec);
202 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_FILL,
203 frameDimensions, 720, 1280, widthSpec, heightSpec);
204 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_BALANCED,
205 frameDimensions, 720, 720, widthSpec, heightSpec);
206 }
207 {
208 // Force height, but relax width constraint. This will force a bad layou t size.
209 final int widthSpec = MeasureSpec.makeMeasureSpec(720, MeasureSpec.AT_MO ST);
210 final int heightSpec = MeasureSpec.makeMeasureSpec(1280, MeasureSpec.EXA CTLY);
211 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_FIT,
212 frameDimensions, 720, 1280, widthSpec, heightSpec);
213 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_FILL,
214 frameDimensions, 720, 1280, widthSpec, heightSpec);
215 assertMeasuredSize(surfaceViewRenderer, RendererCommon.ScalingType.SCALE _ASPECT_BALANCED,
216 frameDimensions, 720, 1280, widthSpec, heightSpec);
217 }
218 }
219
220 surfaceViewRenderer.release();
221 }
222 }
OLDNEW
« no previous file with comments | « no previous file | talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698