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