• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.decoder.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.fail;
23 import static org.junit.Assume.assumeFalse;
24 
25 import android.media.MediaCodec;
26 import android.media.MediaCodecInfo.VideoCapabilities;
27 import android.media.MediaExtractor;
28 import android.media.MediaFormat;
29 import android.media.cts.MediaHeavyPresubmitTest;
30 import android.media.cts.MediaTestBase;
31 import android.media.cts.TestArgs;
32 import android.media.cts.TestUtils;
33 import android.os.Bundle;
34 import android.platform.test.annotations.AppModeFull;
35 import android.text.TextUtils;
36 import android.util.Log;
37 import android.util.Pair;
38 import android.view.Surface;
39 
40 import androidx.test.platform.app.InstrumentationRegistry;
41 
42 import com.android.compatibility.common.util.DeviceReportLog;
43 import com.android.compatibility.common.util.MediaPerfUtils;
44 import com.android.compatibility.common.util.MediaUtils;
45 import com.android.compatibility.common.util.Preconditions;
46 import com.android.compatibility.common.util.ResultType;
47 import com.android.compatibility.common.util.ResultUnit;
48 
49 import org.junit.After;
50 import org.junit.Before;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.junit.runners.Parameterized;
54 
55 import java.nio.ByteBuffer;
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 import java.util.Collection;
59 import java.util.LinkedList;
60 import java.util.List;
61 
62 @MediaHeavyPresubmitTest
63 @AppModeFull(reason = "TODO: evaluate and port to instant")
64 @RunWith(Parameterized.class)
65 public class VideoDecoderPerfTest extends MediaTestBase {
66     private static final String TAG = "VideoDecoderPerfTest";
67     private static final String REPORT_LOG_NAME = "CtsMediaDecoderTestCases";
68     private static final int TOTAL_FRAMES = 30000;
69     private static final int MIN_FRAMES = 3000;
70     private static final int MAX_TIME_MS = 120000;  // 2 minutes
71     private static final int MAX_TEST_TIMEOUT_MS = 300000;  // 5 minutes
72     private static final int MIN_TEST_MS = 10000;  // 10 seconds
73     private static final int NUMBER_OF_REPEATS = 2;
74 
75     private static final String AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
76     private static final String H263 = MediaFormat.MIMETYPE_VIDEO_H263;
77     private static final String HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC;
78     private static final String MPEG2 = MediaFormat.MIMETYPE_VIDEO_MPEG2;
79     private static final String MPEG4 = MediaFormat.MIMETYPE_VIDEO_MPEG4;
80     private static final String VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
81     private static final String VP9 = MediaFormat.MIMETYPE_VIDEO_VP9;
82     private static final String AV1 = MediaFormat.MIMETYPE_VIDEO_AV1;
83 
84     private static final boolean GOOG = true;
85     private static final boolean OTHER = false;
86 
87     private static final int MAX_SIZE_SAMPLES_IN_MEMORY_BYTES = 12 << 20;  // 12MB
88 
89     private final String mDecoderName;
90     private final String mMediaType;
91     private final String[] mResources;
92 
93     // each sample contains the buffer and the PTS offset from the frame index
94     LinkedList<Pair<ByteBuffer, Double>> mSamplesInMemory = new LinkedList<Pair<ByteBuffer, Double>>();
95     private MediaFormat mDecInputFormat;
96     private MediaFormat mDecOutputFormat;
97     private int mBitrate;
98 
99     private boolean mSkipRateChecking = false;
100     private boolean mUpdatedSwCodec = false;
101     static final String mInpPrefix = WorkDir.getMediaDirString();
102 
prepareParamList(List<Object[]> exhaustiveArgsList)103     static private List<Object[]> prepareParamList(List<Object[]> exhaustiveArgsList) {
104         final List<Object[]> argsList = new ArrayList<>();
105         int argLength = exhaustiveArgsList.get(0).length;
106         for (Object[] arg : exhaustiveArgsList) {
107             String mediaType = (String)arg[0];
108             if (TestArgs.shouldSkipMediaType(mediaType)) {
109                 continue;
110             }
111             String[] decoders = MediaUtils.getDecoderNamesForMime(mediaType);
112             for (String decoder : decoders) {
113                 if (TestArgs.shouldSkipCodec(decoder)) {
114                     continue;
115                 }
116                 Object[] testArgs = new Object[argLength + 1];
117                 // Add codec name as first argument and then copy all other arguments passed
118                 testArgs[0] = decoder;
119                 System.arraycopy(arg, 0, testArgs, 1, argLength);
120                 argsList.add(testArgs);
121             }
122         }
123         return argsList;
124     }
125 
126     @Parameterized.Parameters(name = "{index}_{0}_{3}")
input()127     public static Collection<Object[]> input() {
128         final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{
129                 // MediaType, resources, graphics display resolution
130                 {AVC, sAvcMedia0320x0240, "qvga"},
131                 {AVC, sAvcMedia0720x0480, "sd"},
132                 {AVC, sAvcMedia1280x0720, "hd"},
133                 {AVC, sAvcMedia1920x1080, "fullhd"},
134 
135                 {H263, sH263Media0176x0144, "qcif"},
136                 {H263, sH263Media0352x0288, "cif"},
137 
138                 {HEVC, sHevcMedia0352x0288, "cif"},
139                 {HEVC, sHevcMedia0640x0360, "vga"},
140                 {HEVC, sHevcMedia0720x0480, "sd"},
141                 {HEVC, sHevcMedia1280x0720, "hd"},
142                 {HEVC, sHevcMedia1920x1080, "fullhd"},
143                 {HEVC, sHevcMedia3840x2160, "uhd"},
144 
145                 {MPEG4, sMpeg4Media0176x0144, "qcif"},
146                 {MPEG4, sMpeg4Media0480x0360, "360p"},
147                 {MPEG4, sMpeg4Media1280x0720, "hd"},
148 
149                 {VP8, sVp8Media0320x0180, "qvga"},
150                 {VP8, sVp8Media0640x0360, "vga"},
151                 {VP8, sVp8Media1280x0720, "hd"},
152                 {VP8, sVp8Media1920x1080, "fullhd"},
153 
154                 {VP9, sVp9Media0320x0180, "qvga"},
155                 {VP9, sVp9Media0640x0360, "vga"},
156                 {VP9, sVp9Media1280x0720, "hd"},
157                 {VP9, sVp9Media1920x1080, "fullhd"},
158                 {VP9, sVp9Media3840x2160, "uhd"},
159 
160                 {AV1, sAv1Media0352x0288, "cif"},
161                 {AV1, sAv1Media0640x0360, "vga"},
162                 {AV1, sAv1Media0720x0480, "sd"},
163                 {AV1, sAv1Media1280x0720, "hd"},
164                 {AV1, sAv1Media1920x1080, "fullhd"},
165         });
166         return prepareParamList(exhaustiveArgsList);
167     }
168 
VideoDecoderPerfTest(String decodername, String mediaType, String[] resources, @SuppressWarnings("unused") String gfxcode)169     public VideoDecoderPerfTest(String decodername, String mediaType, String[] resources,
170             @SuppressWarnings("unused") String gfxcode) {
171         mDecoderName = decodername;
172         mMediaType = mediaType;
173         mResources = resources;
174     }
175 
176     @Before
177     @Override
setUp()178     public void setUp() throws Throwable {
179         super.setUp();
180         Bundle bundle = InstrumentationRegistry.getArguments();
181         mSkipRateChecking = TextUtils.equals("true", bundle.getString("mts-media"));
182 
183         mUpdatedSwCodec =
184                 !TestUtils.isMainlineModuleFactoryVersion("com.google.android.media.swcodec");
185     }
186 
187     @After
188     @Override
tearDown()189     public void tearDown() {
190         super.tearDown();
191     }
192 
decode(String name, final String resource, MediaFormat format)193     private void decode(String name, final String resource, MediaFormat format) throws Exception {
194         int width = format.getInteger(MediaFormat.KEY_WIDTH);
195         int height = format.getInteger(MediaFormat.KEY_HEIGHT);
196         String mime = format.getString(MediaFormat.KEY_MIME);
197 
198         // Ensure we can finish this test within the test timeout. Allow 25% slack (4/5).
199         long maxTimeMs = Math.min(
200                 MAX_TEST_TIMEOUT_MS * 4 / 5 / NUMBER_OF_REPEATS, MAX_TIME_MS);
201         // reduce test run on non-real device to maximum of 2 seconds
202         if (MediaUtils.onFrankenDevice()) {
203             maxTimeMs = Math.min(2000, maxTimeMs);
204         }
205         double measuredFps[] = new double[NUMBER_OF_REPEATS];
206 
207         for (int i = 0; i < NUMBER_OF_REPEATS; ++i) {
208             // Decode to Surface.
209             Log.d(TAG, "round #" + i + ": " + name + " for " + maxTimeMs + " msecs to surface");
210             Surface s = getActivity().getSurfaceHolder().getSurface();
211             // only verify the result for decode to surface case.
212             measuredFps[i] = doDecode(name, resource, width, height, s, i, maxTimeMs);
213 
214             // We don't test decoding to buffer.
215             // Log.d(TAG, "round #" + i + " decode to buffer");
216             // doDecode(name, video, width, height, null, i, maxTimeMs);
217         }
218 
219         // allow improvements in mainline-updated google-supplied software codecs.
220         boolean fasterIsOk = mUpdatedSwCodec & TestUtils.isMainlineCodec(name);
221         String error =
222             MediaPerfUtils.verifyAchievableFrameRates(name, mime, width, height,
223                            fasterIsOk,  measuredFps);
224         // Performance numbers only make sense on real devices, so skip on non-real devices
225         if ((MediaUtils.onFrankenDevice() || mSkipRateChecking) && error != null) {
226             if (TestUtils.isMtsMode() && TestUtils.isMainlineCodec(name)) {
227                 assumeFalse(error, error.startsWith("Failed to get "));
228             } else {
229                 // ensure there is data, but don't insist that it is correct
230                 assertFalse(error, error.startsWith("Failed to get "));
231             }
232         } else {
233             assertNull(error, error);
234         }
235         mSamplesInMemory.clear();
236     }
237 
doDecode(String name, final String filename, int w, int h, Surface surface, int round, long maxTimeMs)238     private double doDecode(String name, final String filename, int w, int h, Surface surface,
239             int round, long maxTimeMs) throws Exception {
240         final String video = mInpPrefix + filename;
241         Preconditions.assertTestFileExists(video);
242         MediaExtractor extractor = new MediaExtractor();
243         extractor.setDataSource(video);
244         extractor.selectTrack(0);
245         int trackIndex = extractor.getSampleTrackIndex();
246         MediaFormat format = extractor.getTrackFormat(trackIndex);
247         String mime = format.getString(MediaFormat.KEY_MIME);
248 
249         // use frame rate to calculate PTS offset used for PTS scaling
250         double frameRate = 0.; // default - 0 is used for using zero PTS offset
251         if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
252             frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
253         } else if (!mime.equals(MediaFormat.MIMETYPE_VIDEO_VP8)
254                 && !mime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
255             fail("need framerate info for video file");
256         }
257 
258         ByteBuffer[] codecInputBuffers;
259         ByteBuffer[] codecOutputBuffers;
260 
261         if (mSamplesInMemory.size() == 0) {
262             int totalMemory = 0;
263             ByteBuffer tmpBuf = ByteBuffer.allocate(w * h * 3 / 2);
264             int sampleSize = 0;
265             int index = 0;
266             long firstPTS = 0;
267             double presentationOffset = 0.;
268             while ((sampleSize = extractor.readSampleData(tmpBuf, 0 /* offset */)) > 0) {
269                 if (totalMemory + sampleSize > MAX_SIZE_SAMPLES_IN_MEMORY_BYTES) {
270                     break;
271                 }
272                 if (mSamplesInMemory.size() == 0) {
273                     firstPTS = extractor.getSampleTime();
274                 }
275                 ByteBuffer copied = ByteBuffer.allocate(sampleSize);
276                 copied.put(tmpBuf);
277                 if (frameRate > 0.) {
278                     // presentation offset is an offset from the frame index
279                     presentationOffset =
280                         (extractor.getSampleTime() - firstPTS) * frameRate / 1e6 - index;
281                 }
282                 mSamplesInMemory.addLast(Pair.create(copied, presentationOffset));
283                 totalMemory += sampleSize;
284                 ++index;
285                 extractor.advance();
286             }
287             Log.d(TAG, mSamplesInMemory.size() + " samples in memory for " +
288                     (totalMemory / 1024) + " KB.");
289             // bitrate normalized to 30fps
290             mBitrate = (int)Math.round(totalMemory * 30. * 8. / mSamplesInMemory.size());
291         }
292         format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrate);
293 
294         int sampleIndex = 0;
295 
296         extractor.release();
297 
298         MediaCodec codec = MediaCodec.createByCodecName(name);
299         VideoCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities();
300         frameRate = cap.getSupportedFrameRatesFor(w, h).getUpper();
301         codec.configure(format, surface, null /* crypto */, 0 /* flags */);
302         codec.start();
303         codecInputBuffers = codec.getInputBuffers();
304         codecOutputBuffers = codec.getOutputBuffers();
305         mDecInputFormat = codec.getInputFormat();
306 
307         // start decode loop
308         MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
309 
310         final long kTimeOutUs = 1000; // 1ms timeout
311         double[] frameTimeUsDiff = new double[TOTAL_FRAMES - 1];
312         long lastOutputTimeUs = 0;
313         boolean sawInputEOS = false;
314         boolean sawOutputEOS = false;
315         int inputNum = 0;
316         int outputNum = 0;
317         long start = System.currentTimeMillis();
318         while (!sawOutputEOS) {
319             // handle input
320             if (!sawInputEOS) {
321                 int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
322 
323                 if (inputBufIndex >= 0) {
324                     ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
325                     // sample contains the buffer and the PTS offset normalized to frame index
326                     Pair<ByteBuffer, Double> sample =
327                             mSamplesInMemory.get(sampleIndex++ % mSamplesInMemory.size());
328                     sample.first.rewind();
329                     int sampleSize = sample.first.remaining();
330                     dstBuf.put(sample.first);
331                     // use max supported framerate to compute pts
332                     long presentationTimeUs = (long)((inputNum + sample.second) * 1e6 / frameRate);
333 
334                     long elapsed = System.currentTimeMillis() - start;
335                     sawInputEOS = ((++inputNum == TOTAL_FRAMES)
336                                    || (elapsed > maxTimeMs)
337                                    || (elapsed > MIN_TEST_MS && outputNum > MIN_FRAMES));
338                     if (sawInputEOS) {
339                         Log.d(TAG, "saw input EOS (stop at sample).");
340                     }
341                     codec.queueInputBuffer(
342                             inputBufIndex,
343                             0 /* offset */,
344                             sampleSize,
345                             presentationTimeUs,
346                             sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
347                 } else {
348                     assertEquals(
349                             "codec.dequeueInputBuffer() unrecognized return value: " + inputBufIndex,
350                             MediaCodec.INFO_TRY_AGAIN_LATER, inputBufIndex);
351                 }
352             }
353 
354             // handle output
355             int outputBufIndex = codec.dequeueOutputBuffer(info, kTimeOutUs);
356 
357             if (outputBufIndex >= 0) {
358                 if (info.size > 0) { // Disregard 0-sized buffers at the end.
359                     long nowUs = (System.nanoTime() + 500) / 1000;
360                     if (outputNum > 1) {
361                         frameTimeUsDiff[outputNum - 1] = nowUs - lastOutputTimeUs;
362                     }
363                     lastOutputTimeUs = nowUs;
364                     outputNum++;
365                 }
366                 codec.releaseOutputBuffer(outputBufIndex, false /* render */);
367                 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
368                     Log.d(TAG, "saw output EOS.");
369                     sawOutputEOS = true;
370                 }
371             } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
372                 codecOutputBuffers = codec.getOutputBuffers();
373                 Log.d(TAG, "output buffers have changed.");
374             } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
375                 mDecOutputFormat = codec.getOutputFormat();
376                 int width = mDecOutputFormat.getInteger(MediaFormat.KEY_WIDTH);
377                 int height = mDecOutputFormat.getInteger(MediaFormat.KEY_HEIGHT);
378                 Log.d(TAG, "output resolution " + width + "x" + height);
379             } else {
380                 assertEquals(
381                         "codec.dequeueOutputBuffer() unrecognized return index: "
382                                 + outputBufIndex,
383                         MediaCodec.INFO_TRY_AGAIN_LATER, outputBufIndex);
384             }
385         }
386         long finish = System.currentTimeMillis();
387         int validDataNum = outputNum - 1;
388         frameTimeUsDiff = Arrays.copyOf(frameTimeUsDiff, validDataNum);
389         codec.stop();
390         codec.release();
391 
392         Log.d(TAG, "input num " + inputNum + " vs output num " + outputNum);
393 
394         DeviceReportLog log = new DeviceReportLog(REPORT_LOG_NAME, "video_decoder_performance");
395         String message = MediaPerfUtils.addPerformanceHeadersToLog(
396                 log, "decoder stats: decodeTo=" + ((surface == null) ? "buffer" : "surface"),
397                 round, name, format, mDecInputFormat, mDecOutputFormat);
398         log.addValue("video_res", video, ResultType.NEUTRAL, ResultUnit.NONE);
399         log.addValue("decode_to", surface == null ? "buffer" : "surface",
400                 ResultType.NEUTRAL, ResultUnit.NONE);
401 
402         double fps = outputNum / ((finish - start) / 1000.0);
403         log.addValue("average_fps", fps, ResultType.HIGHER_BETTER, ResultUnit.FPS);
404 
405         MediaUtils.Stats stats = new MediaUtils.Stats(frameTimeUsDiff);
406         fps = MediaPerfUtils.addPerformanceStatsToLog(log, stats, message);
407         log.submit(InstrumentationRegistry.getInstrumentation());
408         return fps;
409     }
410 
getVideoTrackFormats(String... resources)411     private MediaFormat[] getVideoTrackFormats(String... resources) throws Exception {
412         MediaFormat[] formats = new MediaFormat[resources.length];
413         for (int i = 0; i < resources.length; ++i) {
414             Preconditions.assertTestFileExists(mInpPrefix + resources[i]);
415             formats[i] = MediaUtils.getTrackFormatForResource(mInpPrefix + resources[i], "video/");
416         }
417         return formats;
418     }
419 
perf(final String decoderName, final String[] resources)420     private void perf(final String decoderName, final String[] resources) throws Exception {
421         MediaFormat[] formats = getVideoTrackFormats(resources);
422         // Decode/measure the first supported video resource
423         for (int i = 0; i < resources.length; ++i) {
424             if (MediaUtils.supports(decoderName, formats[i])) {
425                 decode(decoderName, resources[i], formats[i]);
426                 break;
427             }
428         }
429     }
430 
431     // AVC tests
432 
433     private static final String[] sAvcMedia0320x0240 = {
434         "bbb_s1_320x240_mp4_h264_mp2_800kbps_30fps_aac_lc_5ch_240kbps_44100hz.mp4",
435     };
436 
437     private static final String[] sAvcMedia0720x0480 = {
438         "bbb_s1_720x480_mp4_h264_mp3_2mbps_30fps_aac_lc_5ch_320kbps_48000hz.mp4",
439     };
440 
441     // prefer highest effective bitrate, then high profile
442     private static final String[] sAvcMedia1280x0720 = {
443         "bbb_s4_1280x720_mp4_h264_mp31_8mbps_30fps_aac_he_mono_40kbps_44100hz.mp4",
444         "bbb_s3_1280x720_mp4_h264_hp32_8mbps_60fps_aac_he_v2_stereo_48kbps_48000hz.mp4",
445         "bbb_s3_1280x720_mp4_h264_mp32_8mbps_60fps_aac_he_v2_6ch_144kbps_44100hz.mp4",
446     };
447 
448     // prefer highest effective bitrate, then high profile
449     private static final String[] sAvcMedia1920x1080 = {
450         "bbb_s4_1920x1080_wide_mp4_h264_hp4_20mbps_30fps_aac_lc_6ch_384kbps_44100hz.mp4",
451         "bbb_s4_1920x1080_wide_mp4_h264_mp4_20mbps_30fps_aac_he_5ch_200kbps_44100hz.mp4",
452         "bbb_s2_1920x1080_mp4_h264_hp42_20mbps_60fps_aac_lc_6ch_384kbps_48000hz.mp4",
453         "bbb_s2_1920x1080_mp4_h264_mp42_20mbps_60fps_aac_he_v2_5ch_160kbps_48000hz.mp4",
454     };
455 
456     // H263 tests
457 
458     private static final String[] sH263Media0176x0144 = {
459         "video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz.3gp",
460     };
461 
462     private static final String[] sH263Media0352x0288 = {
463         "video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz.3gp",
464     };
465 
466     // No media for H263 704x576
467 
468     // No media for H263 1408x1152
469 
470     // HEVC tests
471 
472     private static final String[] sHevcMedia0352x0288 = {
473         "bbb_s1_352x288_mp4_hevc_mp2_600kbps_30fps_aac_he_stereo_96kbps_48000hz.mp4",
474     };
475 
476     private static final String[] sHevcMedia0640x0360 = {
477         "bbb_s1_640x360_mp4_hevc_mp21_1600kbps_30fps_aac_he_6ch_288kbps_44100hz.mp4",
478     };
479 
480     private static final String[] sHevcMedia0720x0480 = {
481         "bbb_s1_720x480_mp4_hevc_mp3_1600kbps_30fps_aac_he_6ch_240kbps_48000hz.mp4",
482     };
483 
484     private static final String[] sHevcMedia1280x0720 = {
485         "bbb_s4_1280x720_mp4_hevc_mp31_4mbps_30fps_aac_he_stereo_80kbps_32000hz.mp4",
486     };
487 
488     private static final String[] sHevcMedia1920x1080 = {
489         "bbb_s2_1920x1080_mp4_hevc_mp41_10mbps_60fps_aac_lc_6ch_384kbps_22050hz.mp4",
490     };
491 
492     // prefer highest effective bitrate
493     private static final String[] sHevcMedia3840x2160 = {
494         "bbb_s4_3840x2160_mp4_hevc_mp5_20mbps_30fps_aac_lc_6ch_384kbps_24000hz.mp4",
495         "bbb_s2_3840x2160_mp4_hevc_mp51_20mbps_60fps_aac_lc_6ch_384kbps_32000hz.mp4",
496     };
497 
498     // MPEG2 tests
499 
500     // No media for MPEG2 176x144
501 
502     // No media for MPEG2 352x288
503 
504     // No media for MPEG2 640x480
505 
506     // No media for MPEG2 1280x720
507 
508     // No media for MPEG2 1920x1080
509 
510     // MPEG4 tests
511 
512     private static final String[] sMpeg4Media0176x0144 = {
513         "video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4",
514     };
515 
516     private static final String[] sMpeg4Media0480x0360 = {
517         "video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz.mp4",
518     };
519 
520     // No media for MPEG4 640x480
521 
522     private static final String[] sMpeg4Media1280x0720 = {
523         "video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4",
524     };
525 
526     // VP8 tests
527 
528     private static final String[] sVp8Media0320x0180 = {
529         "bbb_s1_320x180_webm_vp8_800kbps_30fps_opus_5ch_320kbps_48000hz.webm",
530     };
531 
532     private static final String[] sVp8Media0640x0360 = {
533         "bbb_s1_640x360_webm_vp8_2mbps_30fps_vorbis_5ch_320kbps_48000hz.webm",
534     };
535 
536     // prefer highest effective bitrate
537     private static final String[] sVp8Media1280x0720 = {
538         "bbb_s4_1280x720_webm_vp8_8mbps_30fps_opus_mono_64kbps_48000hz.webm",
539         "bbb_s3_1280x720_webm_vp8_8mbps_60fps_opus_6ch_384kbps_48000hz.webm",
540     };
541 
542     // prefer highest effective bitrate
543     private static final String[] sVp8Media1920x1080 = {
544         "bbb_s4_1920x1080_wide_webm_vp8_20mbps_30fps_vorbis_6ch_384kbps_44100hz.webm",
545         "bbb_s2_1920x1080_webm_vp8_20mbps_60fps_vorbis_6ch_384kbps_48000hz.webm",
546     };
547 
548     // VP9 tests
549 
550     private static final String[] sVp9Media0320x0180 = {
551         "bbb_s1_320x180_webm_vp9_0p11_600kbps_30fps_vorbis_mono_64kbps_48000hz.webm",
552     };
553 
554     private static final String[] sVp9Media0640x0360 = {
555         "bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm",
556     };
557 
558     private static final String[] sVp9Media1280x0720 = {
559         "bbb_s4_1280x720_webm_vp9_0p31_4mbps_30fps_opus_stereo_128kbps_48000hz.webm",
560     };
561 
562     private static final String[] sVp9Media1920x1080 = {
563         "bbb_s2_1920x1080_webm_vp9_0p41_10mbps_60fps_vorbis_6ch_384kbps_22050hz.webm",
564     };
565 
566     // prefer highest effective bitrate
567     private static final String[] sVp9Media3840x2160 = {
568         "bbb_s4_3840x2160_webm_vp9_0p5_20mbps_30fps_vorbis_6ch_384kbps_24000hz.webm",
569         "bbb_s2_3840x2160_webm_vp9_0p51_20mbps_60fps_vorbis_6ch_384kbps_32000hz.webm",
570     };
571 
572     // AV1 tests
573 
574     private static final String[] sAv1Media0352x0288 = {
575         "bbb_s1_352x288_mp4_av1_355kbps_30fps_aac_lc_stereo_128kbps_48000hz.mp4",
576     };
577 
578     private static final String[] sAv1Media0640x0360 = {
579         "bbb_s1_640x360_mp4_av1_994kbps_30fps_aac_lc_6ch_342kbps_48000hz.mp4",
580     };
581 
582     private static final String[] sAv1Media0720x0480 = {
583         "bbb_s1_720x480_mp4_av1_977kbps_30fps_aac_lc_6ch_341kbps_48000hz.mp4",
584     };
585 
586     private static final String[] sAv1Media1280x0720 = {
587         "bbb_s4_1280x720_mp4_av1_2387kbps_30fps_aac_lc_stereo_130kbps_32000hz.mp4",
588     };
589 
590     private static final String[] sAv1Media1920x1080 = {
591         "bbb_s2_1920x1080_mp4_av1_5010kbps_60fps_aac_lc_6ch_348kbps_22050hz.mp4",
592     };
593 
594     @Test
testPerf()595     public void testPerf() throws Exception {
596         perf(mDecoderName, mResources);
597     }
598 }
599 
600