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