1 /*
2  *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 package org.webrtc;
12 
13 import static org.junit.Assert.assertArrayEquals;
14 import static org.junit.Assert.assertEquals;
15 import static org.webrtc.RendererCommon.ScalingType.SCALE_ASPECT_BALANCED;
16 import static org.webrtc.RendererCommon.ScalingType.SCALE_ASPECT_FILL;
17 import static org.webrtc.RendererCommon.ScalingType.SCALE_ASPECT_FIT;
18 import static org.webrtc.RendererCommon.getDisplaySize;
19 import static org.webrtc.RendererCommon.getLayoutMatrix;
20 
21 import android.graphics.Point;
22 import android.support.test.filters.SmallTest;
23 import org.chromium.base.test.BaseJUnit4ClassRunner;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 
27 @RunWith(BaseJUnit4ClassRunner.class)
28 public class RendererCommonTest {
29   @Test
30   @SmallTest
testDisplaySizeNoFrame()31   public void testDisplaySizeNoFrame() {
32     assertEquals(new Point(0, 0), getDisplaySize(SCALE_ASPECT_FIT, 0.0f, 0, 0));
33     assertEquals(new Point(0, 0), getDisplaySize(SCALE_ASPECT_FILL, 0.0f, 0, 0));
34     assertEquals(new Point(0, 0), getDisplaySize(SCALE_ASPECT_BALANCED, 0.0f, 0, 0));
35   }
36 
37   @Test
38   @SmallTest
testDisplaySizeDegenerateAspectRatio()39   public void testDisplaySizeDegenerateAspectRatio() {
40     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_FIT, 0.0f, 1280, 720));
41     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_FILL, 0.0f, 1280, 720));
42     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_BALANCED, 0.0f, 1280, 720));
43   }
44 
45   @Test
46   @SmallTest
testZeroDisplaySize()47   public void testZeroDisplaySize() {
48     assertEquals(new Point(0, 0), getDisplaySize(SCALE_ASPECT_FIT, 16.0f / 9, 0, 0));
49     assertEquals(new Point(0, 0), getDisplaySize(SCALE_ASPECT_FILL, 16.0f / 9, 0, 0));
50     assertEquals(new Point(0, 0), getDisplaySize(SCALE_ASPECT_BALANCED, 16.0f / 9, 0, 0));
51   }
52 
53   @Test
54   @SmallTest
testDisplaySizePerfectFit()55   public void testDisplaySizePerfectFit() {
56     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_FIT, 16.0f / 9, 1280, 720));
57     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_FILL, 16.0f / 9, 1280, 720));
58     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_BALANCED, 16.0f / 9, 1280, 720));
59     assertEquals(new Point(720, 1280), getDisplaySize(SCALE_ASPECT_FIT, 9.0f / 16, 720, 1280));
60     assertEquals(new Point(720, 1280), getDisplaySize(SCALE_ASPECT_FILL, 9.0f / 16, 720, 1280));
61     assertEquals(new Point(720, 1280), getDisplaySize(SCALE_ASPECT_BALANCED, 9.0f / 16, 720, 1280));
62   }
63 
64   @Test
65   @SmallTest
testLandscapeVideoInPortraitDisplay()66   public void testLandscapeVideoInPortraitDisplay() {
67     assertEquals(new Point(720, 405), getDisplaySize(SCALE_ASPECT_FIT, 16.0f / 9, 720, 1280));
68     assertEquals(new Point(720, 1280), getDisplaySize(SCALE_ASPECT_FILL, 16.0f / 9, 720, 1280));
69     assertEquals(new Point(720, 720), getDisplaySize(SCALE_ASPECT_BALANCED, 16.0f / 9, 720, 1280));
70   }
71 
72   @Test
73   @SmallTest
testPortraitVideoInLandscapeDisplay()74   public void testPortraitVideoInLandscapeDisplay() {
75     assertEquals(new Point(405, 720), getDisplaySize(SCALE_ASPECT_FIT, 9.0f / 16, 1280, 720));
76     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_FILL, 9.0f / 16, 1280, 720));
77     assertEquals(new Point(720, 720), getDisplaySize(SCALE_ASPECT_BALANCED, 9.0f / 16, 1280, 720));
78   }
79 
80   @Test
81   @SmallTest
testFourToThreeVideoInSixteenToNineDisplay()82   public void testFourToThreeVideoInSixteenToNineDisplay() {
83     assertEquals(new Point(960, 720), getDisplaySize(SCALE_ASPECT_FIT, 4.0f / 3, 1280, 720));
84     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_FILL, 4.0f / 3, 1280, 720));
85     assertEquals(new Point(1280, 720), getDisplaySize(SCALE_ASPECT_BALANCED, 4.0f / 3, 1280, 720));
86   }
87 
88   // Only keep 2 rounded decimals to make float comparison robust.
round(float[] array)89   private static double[] round(float[] array) {
90     assertEquals(16, array.length);
91     final double[] doubleArray = new double[16];
92     for (int i = 0; i < 16; ++i) {
93       doubleArray[i] = Math.round(100 * array[i]) / 100.0;
94     }
95     return doubleArray;
96   }
97 
98   // Brief summary about matrix transformations:
99   // A coordinate p = [u, v, 0, 1] is transformed by matrix m like this p' = [u', v', 0, 1] = m * p.
100   // OpenGL uses column-major order, so:
101   // u' = u * m[0] + v * m[4] + m[12].
102   // v' = u * m[1] + v * m[5] + m[13].
103 
104   @Test
105   @SmallTest
testLayoutMatrixDefault()106   public void testLayoutMatrixDefault() {
107     final float layoutMatrix[] = getLayoutMatrix(false, 1.0f, 1.0f);
108     // Assert:
109     // u' = u.
110     // v' = v.
111     // clang-format off
112     assertArrayEquals(new double[] {
113         1, 0, 0, 0,
114         0, 1, 0, 0,
115         0, 0, 1, 0,
116         0, 0, 0, 1}, round(layoutMatrix), 0.0);
117     // clang-format on
118   }
119 
120   @Test
121   @SmallTest
testLayoutMatrixMirror()122   public void testLayoutMatrixMirror() {
123     final float layoutMatrix[] = getLayoutMatrix(true, 1.0f, 1.0f);
124     // Assert:
125     // u' = 1 - u.
126     // v' = v.
127     // clang-format off
128     assertArrayEquals(new double[] {
129         -1, 0, 0, 0,
130          0, 1, 0, 0,
131          0, 0, 1, 0,
132          1, 0, 0, 1}, round(layoutMatrix), 0.0);
133     // clang-format on
134   }
135 
136   @Test
137   @SmallTest
testLayoutMatrixScale()138   public void testLayoutMatrixScale() {
139     // Video has aspect ratio 2, but layout is square. This will cause only the center part of the
140     // video to be visible, i.e. the u coordinate will go from 0.25 to 0.75 instead of from 0 to 1.
141     final float layoutMatrix[] = getLayoutMatrix(false, 2.0f, 1.0f);
142     // Assert:
143     // u' = 0.25 + 0.5 u.
144     // v' = v.
145     // clang-format off
146     assertArrayEquals(new double[] {
147          0.5, 0, 0, 0,
148            0, 1, 0, 0,
149            0, 0, 1, 0,
150         0.25, 0, 0, 1}, round(layoutMatrix), 0.0);
151     // clang-format on
152   }
153 }
154