1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media.cts;
18 
19 import android.media.cts.R;
20 
21 import android.content.Context;
22 import android.content.res.AssetFileDescriptor;
23 import android.content.res.Resources;
24 import android.media.MediaCodec;
25 import android.media.MediaCodecInfo.VideoCapabilities;
26 import android.media.MediaExtractor;
27 import android.media.MediaFormat;
28 import android.util.Log;
29 import android.util.Pair;
30 import android.view.Surface;
31 
32 import com.android.compatibility.common.util.DeviceReportLog;
33 import com.android.compatibility.common.util.MediaPerfUtils;
34 import com.android.compatibility.common.util.MediaUtils;
35 import com.android.compatibility.common.util.ResultType;
36 import com.android.compatibility.common.util.ResultUnit;
37 
38 import java.nio.ByteBuffer;
39 import java.util.Arrays;
40 import java.util.LinkedList;
41 
42 public class VideoDecoderPerfTest extends MediaPlayerTestBase {
43     private static final String TAG = "VideoDecoderPerfTest";
44     private static final String REPORT_LOG_NAME = "CtsMediaTestCases";
45     private static final int TOTAL_FRAMES = 30000;
46     private static final int MIN_FRAMES = 3000;
47     private static final int MAX_TIME_MS = 120000;  // 2 minutes
48     private static final int MAX_TEST_TIMEOUT_MS = 300000;  // 5 minutes
49     private static final int MIN_TEST_MS = 10000;  // 10 seconds
50     private static final int NUMBER_OF_REPEATS = 2;
51 
52     private static final String AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
53     private static final String H263 = MediaFormat.MIMETYPE_VIDEO_H263;
54     private static final String HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC;
55     private static final String MPEG2 = MediaFormat.MIMETYPE_VIDEO_MPEG2;
56     private static final String MPEG4 = MediaFormat.MIMETYPE_VIDEO_MPEG4;
57     private static final String VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
58     private static final String VP9 = MediaFormat.MIMETYPE_VIDEO_VP9;
59 
60     private static final boolean GOOG = true;
61     private static final boolean OTHER = false;
62 
63     private static final int MAX_SIZE_SAMPLES_IN_MEMORY_BYTES = 12 << 20;  // 12MB
64     // each sample contains the buffer and the PTS offset from the frame index
65     LinkedList<Pair<ByteBuffer, Double>> mSamplesInMemory = new LinkedList<Pair<ByteBuffer, Double>>();
66     private MediaFormat mDecInputFormat;
67     private MediaFormat mDecOutputFormat;
68     private int mBitrate;
69 
70     private Resources mResources;
71 
72     @Override
setUp()73     protected void setUp() throws Exception {
74         super.setUp();
75         mResources = mContext.getResources();
76     }
77 
78     @Override
tearDown()79     protected void tearDown() throws Exception {
80         super.tearDown();
81     }
82 
decode(String name, int resourceId, MediaFormat format)83     private void decode(String name, int resourceId, MediaFormat format) throws Exception {
84         int width = format.getInteger(MediaFormat.KEY_WIDTH);
85         int height = format.getInteger(MediaFormat.KEY_HEIGHT);
86         String mime = format.getString(MediaFormat.KEY_MIME);
87 
88         // Ensure we can finish this test within the test timeout. Allow 25% slack (4/5).
89         long maxTimeMs = Math.min(
90                 MAX_TEST_TIMEOUT_MS * 4 / 5 / NUMBER_OF_REPEATS, MAX_TIME_MS);
91         double measuredFps[] = new double[NUMBER_OF_REPEATS];
92 
93         for (int i = 0; i < NUMBER_OF_REPEATS; ++i) {
94             // Decode to Surface.
95             Log.d(TAG, "round #" + i + ": " + name + " for " + maxTimeMs + " msecs to surface");
96             Surface s = getActivity().getSurfaceHolder().getSurface();
97             // only verify the result for decode to surface case.
98             measuredFps[i] = doDecode(name, resourceId, width, height, s, i, maxTimeMs);
99 
100             // We don't test decoding to buffer.
101             // Log.d(TAG, "round #" + i + " decode to buffer");
102             // doDecode(name, video, width, height, null, i, maxTimeMs);
103         }
104 
105         String error =
106             MediaPerfUtils.verifyAchievableFrameRates(name, mime, width, height, measuredFps);
107         assertNull(error, error);
108         mSamplesInMemory.clear();
109     }
110 
doDecode( String name, int video, int w, int h, Surface surface, int round, long maxTimeMs)111     private double doDecode(
112             String name, int video, int w, int h, Surface surface, int round, long maxTimeMs)
113             throws Exception {
114         AssetFileDescriptor testFd = mResources.openRawResourceFd(video);
115         MediaExtractor extractor = new MediaExtractor();
116         extractor.setDataSource(testFd.getFileDescriptor(), testFd.getStartOffset(),
117                 testFd.getLength());
118         extractor.selectTrack(0);
119         int trackIndex = extractor.getSampleTrackIndex();
120         MediaFormat format = extractor.getTrackFormat(trackIndex);
121         String mime = format.getString(MediaFormat.KEY_MIME);
122 
123         // use frame rate to calculate PTS offset used for PTS scaling
124         double frameRate = 0.; // default - 0 is used for using zero PTS offset
125         if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
126             frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
127         } else if (!mime.equals(MediaFormat.MIMETYPE_VIDEO_VP8)
128                 && !mime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
129             fail("need framerate info for video file");
130         }
131 
132         ByteBuffer[] codecInputBuffers;
133         ByteBuffer[] codecOutputBuffers;
134 
135         if (mSamplesInMemory.size() == 0) {
136             int totalMemory = 0;
137             ByteBuffer tmpBuf = ByteBuffer.allocate(w * h * 3 / 2);
138             int sampleSize = 0;
139             int index = 0;
140             long firstPTS = 0;
141             double presentationOffset = 0.;
142             while ((sampleSize = extractor.readSampleData(tmpBuf, 0 /* offset */)) > 0) {
143                 if (totalMemory + sampleSize > MAX_SIZE_SAMPLES_IN_MEMORY_BYTES) {
144                     break;
145                 }
146                 if (mSamplesInMemory.size() == 0) {
147                     firstPTS = extractor.getSampleTime();
148                 }
149                 ByteBuffer copied = ByteBuffer.allocate(sampleSize);
150                 copied.put(tmpBuf);
151                 if (frameRate > 0.) {
152                     // presentation offset is an offset from the frame index
153                     presentationOffset =
154                         (extractor.getSampleTime() - firstPTS) * frameRate / 1e6 - index;
155                 }
156                 mSamplesInMemory.addLast(Pair.create(copied, presentationOffset));
157                 totalMemory += sampleSize;
158                 ++index;
159                 extractor.advance();
160             }
161             Log.d(TAG, mSamplesInMemory.size() + " samples in memory for " +
162                     (totalMemory / 1024) + " KB.");
163             // bitrate normalized to 30fps
164             mBitrate = (int)Math.round(totalMemory * 30. * 8. / mSamplesInMemory.size());
165         }
166         format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrate);
167 
168         int sampleIndex = 0;
169 
170         extractor.release();
171         testFd.close();
172 
173         MediaCodec codec = MediaCodec.createByCodecName(name);
174         VideoCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities();
175         frameRate = cap.getSupportedFrameRatesFor(w, h).getUpper();
176         codec.configure(format, surface, null /* crypto */, 0 /* flags */);
177         codec.start();
178         codecInputBuffers = codec.getInputBuffers();
179         codecOutputBuffers = codec.getOutputBuffers();
180         mDecInputFormat = codec.getInputFormat();
181 
182         // start decode loop
183         MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
184 
185         final long kTimeOutUs = 1000; // 1ms timeout
186         double[] frameTimeUsDiff = new double[TOTAL_FRAMES - 1];
187         long lastOutputTimeUs = 0;
188         boolean sawInputEOS = false;
189         boolean sawOutputEOS = false;
190         int inputNum = 0;
191         int outputNum = 0;
192         long start = System.currentTimeMillis();
193         while (!sawOutputEOS) {
194             // handle input
195             if (!sawInputEOS) {
196                 int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
197 
198                 if (inputBufIndex >= 0) {
199                     ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
200                     // sample contains the buffer and the PTS offset normalized to frame index
201                     Pair<ByteBuffer, Double> sample =
202                             mSamplesInMemory.get(sampleIndex++ % mSamplesInMemory.size());
203                     sample.first.rewind();
204                     int sampleSize = sample.first.remaining();
205                     dstBuf.put(sample.first);
206                     // use max supported framerate to compute pts
207                     long presentationTimeUs = (long)((inputNum + sample.second) * 1e6 / frameRate);
208 
209                     long elapsed = System.currentTimeMillis() - start;
210                     sawInputEOS = ((++inputNum == TOTAL_FRAMES)
211                                    || (elapsed > maxTimeMs)
212                                    || (elapsed > MIN_TEST_MS && outputNum > MIN_FRAMES));
213                     if (sawInputEOS) {
214                         Log.d(TAG, "saw input EOS (stop at sample).");
215                     }
216                     codec.queueInputBuffer(
217                             inputBufIndex,
218                             0 /* offset */,
219                             sampleSize,
220                             presentationTimeUs,
221                             sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
222                 } else {
223                     assertEquals(
224                             "codec.dequeueInputBuffer() unrecognized return value: " + inputBufIndex,
225                             MediaCodec.INFO_TRY_AGAIN_LATER, inputBufIndex);
226                 }
227             }
228 
229             // handle output
230             int outputBufIndex = codec.dequeueOutputBuffer(info, kTimeOutUs);
231 
232             if (outputBufIndex >= 0) {
233                 if (info.size > 0) { // Disregard 0-sized buffers at the end.
234                     long nowUs = (System.nanoTime() + 500) / 1000;
235                     if (outputNum > 1) {
236                         frameTimeUsDiff[outputNum - 1] = nowUs - lastOutputTimeUs;
237                     }
238                     lastOutputTimeUs = nowUs;
239                     outputNum++;
240                 }
241                 codec.releaseOutputBuffer(outputBufIndex, false /* render */);
242                 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
243                     Log.d(TAG, "saw output EOS.");
244                     sawOutputEOS = true;
245                 }
246             } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
247                 codecOutputBuffers = codec.getOutputBuffers();
248                 Log.d(TAG, "output buffers have changed.");
249             } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
250                 mDecOutputFormat = codec.getOutputFormat();
251                 int width = mDecOutputFormat.getInteger(MediaFormat.KEY_WIDTH);
252                 int height = mDecOutputFormat.getInteger(MediaFormat.KEY_HEIGHT);
253                 Log.d(TAG, "output resolution " + width + "x" + height);
254             } else {
255                 assertEquals(
256                         "codec.dequeueOutputBuffer() unrecognized return index: "
257                                 + outputBufIndex,
258                         MediaCodec.INFO_TRY_AGAIN_LATER, outputBufIndex);
259             }
260         }
261         long finish = System.currentTimeMillis();
262         int validDataNum = outputNum - 1;
263         frameTimeUsDiff = Arrays.copyOf(frameTimeUsDiff, validDataNum);
264         codec.stop();
265         codec.release();
266 
267         Log.d(TAG, "input num " + inputNum + " vs output num " + outputNum);
268 
269         DeviceReportLog log = new DeviceReportLog(REPORT_LOG_NAME, "video_decoder_performance");
270         String message = MediaPerfUtils.addPerformanceHeadersToLog(
271                 log, "decoder stats: decodeTo=" + ((surface == null) ? "buffer" : "surface"),
272                 round, name, format, mDecInputFormat, mDecOutputFormat);
273         log.addValue("video_res", video, ResultType.NEUTRAL, ResultUnit.NONE);
274         log.addValue("decode_to", surface == null ? "buffer" : "surface",
275                 ResultType.NEUTRAL, ResultUnit.NONE);
276 
277         double fps = outputNum / ((finish - start) / 1000.0);
278         log.addValue("average_fps", fps, ResultType.HIGHER_BETTER, ResultUnit.FPS);
279 
280         MediaUtils.Stats stats = new MediaUtils.Stats(frameTimeUsDiff);
281         fps = MediaPerfUtils.addPerformanceStatsToLog(log, stats, message);
282         log.submit(getInstrumentation());
283         return fps;
284     }
285 
getVideoTrackFormats(int... resources)286     private MediaFormat[] getVideoTrackFormats(int... resources) throws Exception {
287         MediaFormat[] formats = new MediaFormat[resources.length];
288         for (int i = 0; i < resources.length; ++i) {
289             formats[i] = MediaUtils.getTrackFormatForResource(mContext, resources[i], "video/");
290         }
291         return formats;
292     }
293 
count(int[] resources, int numGoog, int numOther)294     private void count(int[] resources, int numGoog, int numOther) throws Exception {
295         MediaFormat[] formats = getVideoTrackFormats(resources);
296         MediaUtils.verifyNumCodecs(numGoog,  false /* isEncoder */, true /* isGoog */,  formats);
297         MediaUtils.verifyNumCodecs(numOther, false /* isEncoder */, false /* isGoog */, formats);
298     }
299 
perf(int[] resources, boolean isGoog, int ix)300     private void perf(int[] resources, boolean isGoog, int ix)  throws Exception {
301         MediaFormat[] formats = getVideoTrackFormats(resources);
302         String[] decoders = MediaUtils.getDecoderNames(isGoog, formats);
303         String kind = isGoog ? "Google" : "non-Google";
304         if (decoders.length == 0) {
305             MediaUtils.skipTest("No " + kind + " decoders for " + Arrays.toString(formats));
306             return;
307         } else if (ix >= decoders.length) {
308             Log.i(TAG, "No more " + kind + " decoders for " + Arrays.toString(formats));
309             return;
310         }
311 
312         String decoderName = decoders[ix];
313 
314         // Decode/measure the first supported video resource
315         for (int i = 0; i < resources.length; ++i) {
316             if (MediaUtils.supports(decoderName, formats[i])) {
317                 decode(decoderName, resources[i], formats[i]);
318                 break;
319             }
320         }
321     }
322 
323     // Poor man's Parametrized test as this test must still run on CTSv1 runner.
324 
325     // The count tests are to ensure this Cts test covers all decoders. Add further
326     // tests and change the count if there can be more decoders.
327 
328     // AVC tests
329 
330     private static final int[] sAvcMedia0320x0240 = {
331         R.raw.bbb_s1_320x240_mp4_h264_mp2_800kbps_30fps_aac_lc_5ch_240kbps_44100hz,
332     };
333 
testAvcCount0320x0240()334     public void testAvcCount0320x0240() throws Exception { count(sAvcMedia0320x0240, 1, 4); }
testAvcGoog0Perf0320x0240()335     public void testAvcGoog0Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, GOOG, 0); }
testAvcOther0Perf0320x0240()336     public void testAvcOther0Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 0); }
testAvcOther1Perf0320x0240()337     public void testAvcOther1Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 1); }
testAvcOther2Perf0320x0240()338     public void testAvcOther2Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 2); }
testAvcOther3Perf0320x0240()339     public void testAvcOther3Perf0320x0240() throws Exception { perf(sAvcMedia0320x0240, OTHER, 3); }
340 
341     private static final int[] sAvcMedia0720x0480 = {
342         R.raw.bbb_s1_720x480_mp4_h264_mp3_2mbps_30fps_aac_lc_5ch_320kbps_48000hz,
343     };
344 
testAvcCount0720x0480()345     public void testAvcCount0720x0480() throws Exception { count(sAvcMedia0720x0480, 1, 4); }
testAvcGoog0Perf0720x0480()346     public void testAvcGoog0Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, GOOG, 0); }
testAvcOther0Perf0720x0480()347     public void testAvcOther0Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 0); }
testAvcOther1Perf0720x0480()348     public void testAvcOther1Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 1); }
testAvcOther2Perf0720x0480()349     public void testAvcOther2Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 2); }
testAvcOther3Perf0720x0480()350     public void testAvcOther3Perf0720x0480() throws Exception { perf(sAvcMedia0720x0480, OTHER, 3); }
351 
352     // prefer highest effective bitrate, then high profile
353     private static final int[] sAvcMedia1280x0720 = {
354         R.raw.bbb_s4_1280x720_mp4_h264_mp31_8mbps_30fps_aac_he_mono_40kbps_44100hz,
355         R.raw.bbb_s3_1280x720_mp4_h264_hp32_8mbps_60fps_aac_he_v2_stereo_48kbps_48000hz,
356         R.raw.bbb_s3_1280x720_mp4_h264_mp32_8mbps_60fps_aac_he_v2_6ch_144kbps_44100hz,
357     };
358 
testAvcCount1280x0720()359     public void testAvcCount1280x0720() throws Exception { count(sAvcMedia1280x0720, 1, 4); }
testAvcGoog0Perf1280x0720()360     public void testAvcGoog0Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, GOOG, 0); }
testAvcOther0Perf1280x0720()361     public void testAvcOther0Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 0); }
testAvcOther1Perf1280x0720()362     public void testAvcOther1Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 1); }
testAvcOther2Perf1280x0720()363     public void testAvcOther2Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 2); }
testAvcOther3Perf1280x0720()364     public void testAvcOther3Perf1280x0720() throws Exception { perf(sAvcMedia1280x0720, OTHER, 3); }
365 
366     // prefer highest effective bitrate, then high profile
367     private static final int[] sAvcMedia1920x1080 = {
368         R.raw.bbb_s4_1920x1080_wide_mp4_h264_hp4_20mbps_30fps_aac_lc_6ch_384kbps_44100hz,
369         R.raw.bbb_s4_1920x1080_wide_mp4_h264_mp4_20mbps_30fps_aac_he_5ch_200kbps_44100hz,
370         R.raw.bbb_s2_1920x1080_mp4_h264_hp42_20mbps_60fps_aac_lc_6ch_384kbps_48000hz,
371         R.raw.bbb_s2_1920x1080_mp4_h264_mp42_20mbps_60fps_aac_he_v2_5ch_160kbps_48000hz,
372     };
373 
testAvcCount1920x1080()374     public void testAvcCount1920x1080() throws Exception { count(sAvcMedia1920x1080, 1, 4); }
testAvcGoog0Perf1920x1080()375     public void testAvcGoog0Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, GOOG, 0); }
testAvcOther0Perf1920x1080()376     public void testAvcOther0Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 0); }
testAvcOther1Perf1920x1080()377     public void testAvcOther1Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 1); }
testAvcOther2Perf1920x1080()378     public void testAvcOther2Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 2); }
testAvcOther3Perf1920x1080()379     public void testAvcOther3Perf1920x1080() throws Exception { perf(sAvcMedia1920x1080, OTHER, 3); }
380 
381     // H263 tests
382 
383     private static final int[] sH263Media0176x0144 = {
384         R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
385     };
386 
testH263Count0176x0144()387     public void testH263Count0176x0144() throws Exception { count(sH263Media0176x0144, 1, 2); }
testH263Goog0Perf0176x0144()388     public void testH263Goog0Perf0176x0144() throws Exception { perf(sH263Media0176x0144, GOOG, 0); }
testH263Other0Perf0176x0144()389     public void testH263Other0Perf0176x0144() throws Exception { perf(sH263Media0176x0144, OTHER, 0); }
testH263Other1Perf0176x0144()390     public void testH263Other1Perf0176x0144() throws Exception { perf(sH263Media0176x0144, OTHER, 1); }
391 
392     private static final int[] sH263Media0352x0288 = {
393         R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
394     };
395 
testH263Count0352x0288()396     public void testH263Count0352x0288() throws Exception { count(sH263Media0352x0288, 1, 2); }
testH263Goog0Perf0352x0288()397     public void testH263Goog0Perf0352x0288() throws Exception { perf(sH263Media0352x0288, GOOG, 0); }
testH263Other0Perf0352x0288()398     public void testH263Other0Perf0352x0288() throws Exception { perf(sH263Media0352x0288, OTHER, 0); }
testH263Other1Perf0352x0288()399     public void testH263Other1Perf0352x0288() throws Exception { perf(sH263Media0352x0288, OTHER, 1); }
400 
401     // No media for H263 704x576
402 
403     // No media for H263 1408x1152
404 
405     // HEVC tests
406 
407     private static final int[] sHevcMedia0352x0288 = {
408         R.raw.bbb_s1_352x288_mp4_hevc_mp2_600kbps_30fps_aac_he_stereo_96kbps_48000hz,
409     };
410 
testHevcCount0352x0288()411     public void testHevcCount0352x0288() throws Exception { count(sHevcMedia0352x0288, 1, 4); }
testHevcGoog0Perf0352x0288()412     public void testHevcGoog0Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, GOOG, 0); }
testHevcOther0Perf0352x0288()413     public void testHevcOther0Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 0); }
testHevcOther1Perf0352x0288()414     public void testHevcOther1Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 1); }
testHevcOther2Perf0352x0288()415     public void testHevcOther2Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 2); }
testHevcOther3Perf0352x0288()416     public void testHevcOther3Perf0352x0288() throws Exception { perf(sHevcMedia0352x0288, OTHER, 3); }
417 
418     private static final int[] sHevcMedia0640x0360 = {
419         R.raw.bbb_s1_640x360_mp4_hevc_mp21_1600kbps_30fps_aac_he_6ch_288kbps_44100hz,
420     };
421 
testHevcCount0640x0360()422     public void testHevcCount0640x0360() throws Exception { count(sHevcMedia0640x0360, 1, 4); }
testHevcGoog0Perf0640x0360()423     public void testHevcGoog0Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, GOOG, 0); }
testHevcOther0Perf0640x0360()424     public void testHevcOther0Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 0); }
testHevcOther1Perf0640x0360()425     public void testHevcOther1Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 1); }
testHevcOther2Perf0640x0360()426     public void testHevcOther2Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 2); }
testHevcOther3Perf0640x0360()427     public void testHevcOther3Perf0640x0360() throws Exception { perf(sHevcMedia0640x0360, OTHER, 3); }
428 
429     private static final int[] sHevcMedia0720x0480 = {
430         R.raw.bbb_s1_720x480_mp4_hevc_mp3_1600kbps_30fps_aac_he_6ch_240kbps_48000hz,
431     };
432 
testHevcCount0720x0480()433     public void testHevcCount0720x0480() throws Exception { count(sHevcMedia0720x0480, 1, 4); }
testHevcGoog0Perf0720x0480()434     public void testHevcGoog0Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, GOOG, 0); }
testHevcOther0Perf0720x0480()435     public void testHevcOther0Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 0); }
testHevcOther1Perf0720x0480()436     public void testHevcOther1Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 1); }
testHevcOther2Perf0720x0480()437     public void testHevcOther2Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 2); }
testHevcOther3Perf0720x0480()438     public void testHevcOther3Perf0720x0480() throws Exception { perf(sHevcMedia0720x0480, OTHER, 3); }
439 
440     private static final int[] sHevcMedia1280x0720 = {
441         R.raw.bbb_s4_1280x720_mp4_hevc_mp31_4mbps_30fps_aac_he_stereo_80kbps_32000hz,
442     };
443 
testHevcCount1280x0720()444     public void testHevcCount1280x0720() throws Exception { count(sHevcMedia1280x0720, 1, 4); }
testHevcGoog0Perf1280x0720()445     public void testHevcGoog0Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, GOOG, 0); }
testHevcOther0Perf1280x0720()446     public void testHevcOther0Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 0); }
testHevcOther1Perf1280x0720()447     public void testHevcOther1Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 1); }
testHevcOther2Perf1280x0720()448     public void testHevcOther2Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 2); }
testHevcOther3Perf1280x0720()449     public void testHevcOther3Perf1280x0720() throws Exception { perf(sHevcMedia1280x0720, OTHER, 3); }
450 
451     private static final int[] sHevcMedia1920x1080 = {
452         R.raw.bbb_s2_1920x1080_mp4_hevc_mp41_10mbps_60fps_aac_lc_6ch_384kbps_22050hz,
453     };
454 
testHevcCount1920x1080()455     public void testHevcCount1920x1080() throws Exception { count(sHevcMedia1920x1080, 1, 4); }
testHevcGoog0Perf1920x1080()456     public void testHevcGoog0Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, GOOG, 0); }
testHevcOther0Perf1920x1080()457     public void testHevcOther0Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 0); }
testHevcOther1Perf1920x1080()458     public void testHevcOther1Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 1); }
testHevcOther2Perf1920x1080()459     public void testHevcOther2Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 2); }
testHevcOther3Perf1920x1080()460     public void testHevcOther3Perf1920x1080() throws Exception { perf(sHevcMedia1920x1080, OTHER, 3); }
461 
462     // prefer highest effective bitrate
463     private static final int[] sHevcMedia3840x2160 = {
464         R.raw.bbb_s4_3840x2160_mp4_hevc_mp5_20mbps_30fps_aac_lc_6ch_384kbps_24000hz,
465         R.raw.bbb_s2_3840x2160_mp4_hevc_mp51_20mbps_60fps_aac_lc_6ch_384kbps_32000hz,
466     };
467 
testHevcCount3840x2160()468     public void testHevcCount3840x2160() throws Exception { count(sHevcMedia3840x2160, 1, 4); }
testHevcGoog0Perf3840x2160()469     public void testHevcGoog0Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, GOOG, 0); }
testHevcOther0Perf3840x2160()470     public void testHevcOther0Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 0); }
testHevcOther1Perf3840x2160()471     public void testHevcOther1Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 1); }
testHevcOther2Perf3840x2160()472     public void testHevcOther2Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 2); }
testHevcOther3Perf3840x2160()473     public void testHevcOther3Perf3840x2160() throws Exception { perf(sHevcMedia3840x2160, OTHER, 3); }
474 
475     // MPEG2 tests
476 
477     // No media for MPEG2 176x144
478 
479     // No media for MPEG2 352x288
480 
481     // No media for MPEG2 640x480
482 
483     // No media for MPEG2 1280x720
484 
485     // No media for MPEG2 1920x1080
486 
487     // MPEG4 tests
488 
489     private static final int[] sMpeg4Media0176x0144 = {
490         R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
491     };
492 
testMpeg4Count0176x0144()493     public void testMpeg4Count0176x0144() throws Exception { count(sMpeg4Media0176x0144, 1, 4); }
testMpeg4Goog0Perf0176x0144()494     public void testMpeg4Goog0Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, GOOG, 0); }
testMpeg4Other0Perf0176x0144()495     public void testMpeg4Other0Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 0); }
testMpeg4Other1Perf0176x0144()496     public void testMpeg4Other1Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 1); }
testMpeg4Other2Perf0176x0144()497     public void testMpeg4Other2Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 2); }
testMpeg4Other3Perf0176x0144()498     public void testMpeg4Other3Perf0176x0144() throws Exception { perf(sMpeg4Media0176x0144, OTHER, 3); }
499 
500     private static final int[] sMpeg4Media0480x0360 = {
501         R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
502     };
503 
testMpeg4Count0480x0360()504     public void testMpeg4Count0480x0360() throws Exception { count(sMpeg4Media0480x0360, 1, 4); }
testMpeg4Goog0Perf0480x0360()505     public void testMpeg4Goog0Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, GOOG, 0); }
testMpeg4Other0Perf0480x0360()506     public void testMpeg4Other0Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 0); }
testMpeg4Other1Perf0480x0360()507     public void testMpeg4Other1Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 1); }
testMpeg4Other2Perf0480x0360()508     public void testMpeg4Other2Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 2); }
testMpeg4Other3Perf0480x0360()509     public void testMpeg4Other3Perf0480x0360() throws Exception { perf(sMpeg4Media0480x0360, OTHER, 3); }
510 
511    // No media for MPEG4 640x480
512 
513     private static final int[] sMpeg4Media1280x0720 = {
514         R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
515     };
516 
testMpeg4Count1280x0720()517     public void testMpeg4Count1280x0720() throws Exception { count(sMpeg4Media1280x0720, 1, 4); }
testMpeg4Goog0Perf1280x0720()518     public void testMpeg4Goog0Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, GOOG, 0); }
testMpeg4Other0Perf1280x0720()519     public void testMpeg4Other0Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 0); }
testMpeg4Other1Perf1280x0720()520     public void testMpeg4Other1Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 1); }
testMpeg4Other2Perf1280x0720()521     public void testMpeg4Other2Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 2); }
testMpeg4Other3Perf1280x0720()522     public void testMpeg4Other3Perf1280x0720() throws Exception { perf(sMpeg4Media1280x0720, OTHER, 3); }
523 
524     // VP8 tests
525 
526     private static final int[] sVp8Media0320x0180 = {
527         R.raw.bbb_s1_320x180_webm_vp8_800kbps_30fps_opus_5ch_320kbps_48000hz,
528     };
529 
testVp8Count0320x0180()530     public void testVp8Count0320x0180() throws Exception { count(sVp8Media0320x0180, 1, 2); }
testVp8Goog0Perf0320x0180()531     public void testVp8Goog0Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, GOOG, 0); }
testVp8Other0Perf0320x0180()532     public void testVp8Other0Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, OTHER, 0); }
testVp8Other1Perf0320x0180()533     public void testVp8Other1Perf0320x0180() throws Exception { perf(sVp8Media0320x0180, OTHER, 1); }
534 
535     private static final int[] sVp8Media0640x0360 = {
536         R.raw.bbb_s1_640x360_webm_vp8_2mbps_30fps_vorbis_5ch_320kbps_48000hz,
537     };
538 
testVp8Count0640x0360()539     public void testVp8Count0640x0360() throws Exception { count(sVp8Media0640x0360, 1, 2); }
testVp8Goog0Perf0640x0360()540     public void testVp8Goog0Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, GOOG, 0); }
testVp8Other0Perf0640x0360()541     public void testVp8Other0Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, OTHER, 0); }
testVp8Other1Perf0640x0360()542     public void testVp8Other1Perf0640x0360() throws Exception { perf(sVp8Media0640x0360, OTHER, 1); }
543 
544     // prefer highest effective bitrate
545     private static final int[] sVp8Media1280x0720 = {
546         R.raw.bbb_s4_1280x720_webm_vp8_8mbps_30fps_opus_mono_64kbps_48000hz,
547         R.raw.bbb_s3_1280x720_webm_vp8_8mbps_60fps_opus_6ch_384kbps_48000hz,
548     };
549 
testVp8Count1280x0720()550     public void testVp8Count1280x0720() throws Exception { count(sVp8Media1280x0720, 1, 2); }
testVp8Goog0Perf1280x0720()551     public void testVp8Goog0Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, GOOG, 0); }
testVp8Other0Perf1280x0720()552     public void testVp8Other0Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, OTHER, 0); }
testVp8Other1Perf1280x0720()553     public void testVp8Other1Perf1280x0720() throws Exception { perf(sVp8Media1280x0720, OTHER, 1); }
554 
555     // prefer highest effective bitrate
556     private static final int[] sVp8Media1920x1080 = {
557         R.raw.bbb_s4_1920x1080_wide_webm_vp8_20mbps_30fps_vorbis_6ch_384kbps_44100hz,
558         R.raw.bbb_s2_1920x1080_webm_vp8_20mbps_60fps_vorbis_6ch_384kbps_48000hz,
559     };
560 
testVp8Count1920x1080()561     public void testVp8Count1920x1080() throws Exception { count(sVp8Media1920x1080, 1, 2); }
testVp8Goog0Perf1920x1080()562     public void testVp8Goog0Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, GOOG, 0); }
testVp8Other0Perf1920x1080()563     public void testVp8Other0Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, OTHER, 0); }
testVp8Other1Perf1920x1080()564     public void testVp8Other1Perf1920x1080() throws Exception { perf(sVp8Media1920x1080, OTHER, 1); }
565 
566     // VP9 tests
567 
568     private static final int[] sVp9Media0320x0180 = {
569         R.raw.bbb_s1_320x180_webm_vp9_0p11_600kbps_30fps_vorbis_mono_64kbps_48000hz,
570     };
571 
testVp9Count0320x0180()572     public void testVp9Count0320x0180() throws Exception { count(sVp9Media0320x0180, 1, 4); }
testVp9Goog0Perf0320x0180()573     public void testVp9Goog0Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, GOOG, 0); }
testVp9Other0Perf0320x0180()574     public void testVp9Other0Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 0); }
testVp9Other1Perf0320x0180()575     public void testVp9Other1Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 1); }
testVp9Other2Perf0320x0180()576     public void testVp9Other2Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 2); }
testVp9Other3Perf0320x0180()577     public void testVp9Other3Perf0320x0180() throws Exception { perf(sVp9Media0320x0180, OTHER, 3); }
578 
579     private static final int[] sVp9Media0640x0360 = {
580         R.raw.bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz,
581     };
582 
testVp9Count0640x0360()583     public void testVp9Count0640x0360() throws Exception { count(sVp9Media0640x0360, 1, 4); }
testVp9Goog0Perf0640x0360()584     public void testVp9Goog0Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, GOOG, 0); }
testVp9Other0Perf0640x0360()585     public void testVp9Other0Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 0); }
testVp9Other1Perf0640x0360()586     public void testVp9Other1Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 1); }
testVp9Other2Perf0640x0360()587     public void testVp9Other2Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 2); }
testVp9Other3Perf0640x0360()588     public void testVp9Other3Perf0640x0360() throws Exception { perf(sVp9Media0640x0360, OTHER, 3); }
589 
590     private static final int[] sVp9Media1280x0720 = {
591         R.raw.bbb_s4_1280x720_webm_vp9_0p31_4mbps_30fps_opus_stereo_128kbps_48000hz,
592     };
593 
testVp9Count1280x0720()594     public void testVp9Count1280x0720() throws Exception { count(sVp9Media1280x0720, 1, 4); }
testVp9Goog0Perf1280x0720()595     public void testVp9Goog0Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, GOOG, 0); }
testVp9Other0Perf1280x0720()596     public void testVp9Other0Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 0); }
testVp9Other1Perf1280x0720()597     public void testVp9Other1Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 1); }
testVp9Other2Perf1280x0720()598     public void testVp9Other2Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 2); }
testVp9Other3Perf1280x0720()599     public void testVp9Other3Perf1280x0720() throws Exception { perf(sVp9Media1280x0720, OTHER, 3); }
600 
601     private static final int[] sVp9Media1920x1080 = {
602         R.raw.bbb_s2_1920x1080_webm_vp9_0p41_10mbps_60fps_vorbis_6ch_384kbps_22050hz,
603     };
604 
testVp9Count1920x1080()605     public void testVp9Count1920x1080() throws Exception { count(sVp9Media1920x1080, 1, 4); }
testVp9Goog0Perf1920x1080()606     public void testVp9Goog0Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, GOOG, 0); }
testVp9Other0Perf1920x1080()607     public void testVp9Other0Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 0); }
testVp9Other1Perf1920x1080()608     public void testVp9Other1Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 1); }
testVp9Other2Perf1920x1080()609     public void testVp9Other2Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 2); }
testVp9Other3Perf1920x1080()610     public void testVp9Other3Perf1920x1080() throws Exception { perf(sVp9Media1920x1080, OTHER, 3); }
611 
612     // prefer highest effective bitrate
613     private static final int[] sVp9Media3840x2160 = {
614         R.raw.bbb_s4_3840x2160_webm_vp9_0p5_20mbps_30fps_vorbis_6ch_384kbps_24000hz,
615         R.raw.bbb_s2_3840x2160_webm_vp9_0p51_20mbps_60fps_vorbis_6ch_384kbps_32000hz,
616     };
617 
testVp9Count3840x2160()618     public void testVp9Count3840x2160() throws Exception { count(sVp9Media3840x2160, 1, 4); }
testVp9Goog0Perf3840x2160()619     public void testVp9Goog0Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, GOOG, 0); }
testVp9Other0Perf3840x2160()620     public void testVp9Other0Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 0); }
testVp9Other1Perf3840x2160()621     public void testVp9Other1Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 1); }
testVp9Other2Perf3840x2160()622     public void testVp9Other2Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 2); }
testVp9Other3Perf3840x2160()623     public void testVp9Other3Perf3840x2160() throws Exception { perf(sVp9Media3840x2160, OTHER, 3); }
624 }
625 
626