• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.mediav2.cts;
18 
19 import static android.media.MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR_FD;
20 import static android.media.MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ;
21 import static android.mediav2.common.cts.CodecTestBase.MEDIA_CODEC_LIST_ALL;
22 import static android.mediav2.common.cts.CodecTestBase.PER_TEST_TIMEOUT_SMALL_TEST_MS;
23 import static android.mediav2.common.cts.CodecTestBase.codecFilter;
24 import static android.mediav2.common.cts.CodecTestBase.codecPrefix;
25 import static android.mediav2.common.cts.CodecTestBase.getMaxSupportedInstances;
26 import static android.mediav2.common.cts.CodecTestBase.isFeatureRequired;
27 import static android.mediav2.common.cts.CodecTestBase.isFeatureSupported;
28 import static android.mediav2.common.cts.CodecTestBase.isFormatSupported;
29 import static android.mediav2.common.cts.CodecTestBase.isHardwareAcceleratedCodec;
30 import static android.mediav2.common.cts.CodecTestBase.isSoftwareCodec;
31 import static android.mediav2.common.cts.DecodeStreamToYuv.getFormatInStream;
32 
33 import android.media.MediaCodecInfo;
34 import android.media.MediaFormat;
35 import android.media.cts.TestUtils;
36 import android.util.Range;
37 import android.util.Size;
38 
39 import androidx.test.filters.SdkSuppress;
40 import androidx.test.filters.SmallTest;
41 
42 import com.android.compatibility.common.util.ApiTest;
43 
44 import org.junit.Assert;
45 import org.junit.Assume;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.junit.runners.Parameterized;
49 
50 import java.io.IOException;
51 import java.nio.file.Files;
52 import java.nio.file.Path;
53 import java.nio.file.Paths;
54 import java.util.ArrayList;
55 import java.util.Collection;
56 import java.util.List;
57 import java.util.stream.Stream;
58 
59 /**
60  * This class validates the NDK api for media codec capabilities. The scope of this test is to only
61  * check if the information advertised is ok. If the component is actually capable of supporting the
62  * advertised information is beyond the scope of the test.
63  */
64 @SdkSuppress(minSdkVersion = 36)
65 @SmallTest
66 @RunWith(Parameterized.class)
67 public class NativeAMediaCodecInfoTest {
68     private static final String MEDIA_DIR = WorkDir.getMediaDirString();
69     // in sync with AMediaCodecType values
70     private static final int SOFTWARE_ONLY = 1;
71     private static final int HARDWARE_ACCELERATED = 2;
72     private static final int SOFTWARE_WITH_DEVICE_ACCESS = 3;
73     // alias to MediaCodecInfo.CodecCapabilities.FEATURE_SpecialCodec
74     static final String SPECIAL_CODEC = "special-codec";
75 
76     private static final int MEDIACODEC_KIND_INVALID = 0;
77     private static final int MEDIACODEC_KIND_DECODER = 1;
78     private static final int MEDIACODEC_KIND_ENCODER = 2;
79 
80     private final String mCodecName;
81     private final String mMediaType;
82     private final StringBuilder mTestResults = new StringBuilder();
83 
84     private static final Size SUBQCIF = new Size(128, 96);
85     private static final Size QCIF = new Size(176, 144);
86     private static final Size SD144P = new Size(256, 144);
87     private static final Size CIFNTSC = new Size(352, 240);
88     private static final Size CIF = new Size(352, 288);
89     private static final Size QVGA = new Size(320, 240);
90     private static final Size SD240P = new Size(426, 240);
91     private static final Size SD360P = new Size(640, 360);
92     private static final Size VGA = new Size(640, 480);
93     private static final Size SDNTSC = new Size(720, 480);
94     private static final Size SDPAL = new Size(720, 576);
95     private static final Size WVGA = new Size(800, 480);
96     private static final Size SD480P = new Size(854, 480);
97     private static final Size HD = new Size(1280, 720);
98     private static final Size HDPAL = new Size(1440, 1080);
99     private static final Size FULLHD = new Size(1920, 1080);
100     private static final Size FULLHD_ALT = new Size(1920, 1088);
101     private static final Size UHD1440P = new Size(2560, 1440);
102     private static final Size UHD = new Size(3840, 2160);
103     private static final Size DC4K = new Size(4096, 2160);
104     private static final Size UHD8K = new Size(7680, 4320);
105     private final double[] STANDARD_FPS =
106             {12.0, 15.0, 23.976, 24.0, 25.0, 29.97, 30.0, 48.0, 50.0, 59.94, 60.0};
107     private final Size[] STANDARD_RES =
108             {SUBQCIF, QCIF, SD144P, CIFNTSC, CIF, QVGA, SD240P, SD360P, VGA, SDNTSC, SDPAL, WVGA,
109                     SD480P, HD, HDPAL, FULLHD, FULLHD_ALT, UHD1440P, UHD, DC4K, UHD8K};
110     private final Range<Integer> UNSUPPORTED_SIZE = Range.create(-1, -1);
111     private final Range<Double> UNSUPPORTED_RATE = Range.create(-1.0, -1.0);
112     private final Range<Double> UNKNOWN_RATE = Range.create(-2.0, -2.0);
113 
114     static {
115         System.loadLibrary("ctsmediav2codecinfo_jni");
116     }
117 
118     @Parameterized.Parameters(name = "{index}_{0}_{1}")
input()119     public static Collection<Object[]> input() {
120         final List<Object[]> argsList = new ArrayList<>();
121         for (MediaCodecInfo codecInfo : MEDIA_CODEC_LIST_ALL.getCodecInfos()) {
122             if (codecInfo.isAlias()) continue;
123             String codecName = codecInfo.getName();
124             if (!TestUtils.isTestableCodecInCurrentMode(codecName)) {
125                 continue;
126             }
127             if (codecPrefix != null && !codecName.startsWith(codecPrefix)
128                     || (codecFilter != null && !codecFilter.matcher(codecName).matches())) {
129                 continue;
130             }
131             String[] types = codecInfo.getSupportedTypes();
132             // For codecs supporting multiple media types, the ndk codec names are different from
133             // the sdk names. Skip these codecs as a workaround.
134             if (types.length > 1) {
135                 continue;
136             }
137             for (String type : types) {
138                 if (codecInfo.getCapabilitiesForType(type).isFeatureSupported(SPECIAL_CODEC)) {
139                     continue;
140                 }
141                 argsList.add(new Object[]{codecName, type});
142             }
143         }
144         return argsList;
145     }
146 
NativeAMediaCodecInfoTest(String codecName, String mediaType)147     public NativeAMediaCodecInfoTest(String codecName, String mediaType) {
148         mCodecName = codecName;
149         mMediaType = mediaType;
150     }
151 
getCodecInfo(String codecName)152     public static MediaCodecInfo getCodecInfo(String codecName) {
153         for (MediaCodecInfo info : MEDIA_CODEC_LIST_ALL.getCodecInfos()) {
154             if (info.getName().equals(codecName)) {
155                 return info;
156             }
157         }
158         return null;
159     }
160 
getExpectedCodecType(String codecName)161     private static int getExpectedCodecType(String codecName) {
162         if (isSoftwareCodec(codecName)) {
163             return SOFTWARE_ONLY;
164         } else if (isHardwareAcceleratedCodec(codecName)) {
165             return HARDWARE_ACCELERATED;
166         } else {
167             return SOFTWARE_WITH_DEVICE_ACCESS;
168         }
169     }
170 
getExpectedCodecKind(boolean isEncoder)171     private static int getExpectedCodecKind(boolean isEncoder) {
172         return isEncoder ? MEDIACODEC_KIND_ENCODER : MEDIACODEC_KIND_DECODER;
173     }
174 
getSupportedWidthsForNoExcep(MediaCodecInfo.VideoCapabilities videoCaps, int height)175     private Range<Integer> getSupportedWidthsForNoExcep(MediaCodecInfo.VideoCapabilities videoCaps,
176             int height) {
177         try {
178             return videoCaps.getSupportedWidthsFor(height);
179         } catch (IllegalArgumentException ignored) {
180             return UNSUPPORTED_SIZE;
181         }
182     }
183 
getSupportedHeightsForNoExcep(MediaCodecInfo.VideoCapabilities videoCaps, int width)184     private Range<Integer> getSupportedHeightsForNoExcep(MediaCodecInfo.VideoCapabilities videoCaps,
185             int width) {
186         try {
187             return videoCaps.getSupportedHeightsFor(width);
188         } catch (IllegalArgumentException ignored) {
189             return UNSUPPORTED_SIZE;
190         }
191     }
192 
getSupportedFrameRatesForNoExcep( MediaCodecInfo.VideoCapabilities videoCaps, int width, int height)193     private Range<Double> getSupportedFrameRatesForNoExcep(
194             MediaCodecInfo.VideoCapabilities videoCaps, int width, int height) {
195         try {
196             return videoCaps.getSupportedFrameRatesFor(width, height);
197         } catch (IllegalArgumentException ignored) {
198             return UNSUPPORTED_RATE;
199         }
200     }
201 
getAchievableFrameRatesForNoExcep( MediaCodecInfo.VideoCapabilities videoCaps, int width, int height)202     private Range<Double> getAchievableFrameRatesForNoExcep(
203             MediaCodecInfo.VideoCapabilities videoCaps, int width, int height) {
204         try {
205             Range<Double> rates = videoCaps.getAchievableFrameRatesFor(width, height);
206             return rates == null ? UNKNOWN_RATE : rates;
207         } catch (IllegalArgumentException ignored) {
208             return UNSUPPORTED_RATE;
209         }
210     }
211 
212     @ApiTest(apis = {"AMediaCodecInfo_getKind", "AMediaCodecInfo_isVendor",
213             "AMediaCodecInfo_getCanonicalName", "AMediaCodecInfo_getMaxSupportedInstances",
214             "AMediaCodecInfo_getMediaCodecInfoType", "AMediaCodecInfo_getMediaType",
215             "AMediaCodecInfo_isFeatureSupported", "AMediaCodecInfo_isFeatureRequired",
216             "AMediaCodecInfo_isFormatSupported", "AMediaCodecInfo_getAudioCapabilities",
217             "AMediaCodecInfo_getVideoCapabilities", "AMediaCodecInfo_getEncoderCapabilities"})
218     @SmallTest
219     @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
testAMediaCodecInfoNative()220     public void testAMediaCodecInfoNative() throws IOException {
221         MediaCodecInfo codecInfo = getCodecInfo(mCodecName);
222         Assert.assertNotNull("received null codecInfo for component: " + mCodecName, codecInfo);
223         String[] features = codecInfo.getCapabilitiesForType(mMediaType).validFeatures();
224         Assert.assertNotNull("received null features for component: " + mCodecName, features);
225         Assert.assertTrue("received 0 features for component: " + mCodecName, features.length > 0);
226         boolean isEncoder = codecInfo.isEncoder();
227         int expectedKind = getExpectedCodecKind(isEncoder);
228         int featureSupportMap = 0;
229         int featureRequiredMap = 0;
230         for (int i = 0; i < features.length; i++) {
231             if (isFeatureSupported(mCodecName, mMediaType, features[i])) {
232                 featureSupportMap |= (1 << i);
233             }
234             if (isFeatureRequired(mCodecName, mMediaType, features[i])) {
235                 featureRequiredMap |= (1 << i);
236             }
237         }
238         ArrayList<String> fileList = new ArrayList<>();
239         ArrayList<MediaFormat> formatList = new ArrayList<>();
240         try (Stream<Path> paths = Files.walk(Paths.get(MEDIA_DIR))) {
241             paths.forEach(path -> {
242                 if (Files.isRegularFile(path)) {
243                     try {
244                         MediaFormat format = getFormatInStream(mMediaType, path.toString());
245                         fileList.add(path.toString());
246                         formatList.add(format);
247                     } catch (IOException | IllegalArgumentException ignored) {
248                     }
249                 }
250             });
251         }
252         String[] files = fileList.toArray(new String[0]);
253         boolean[] isFormatSupportedArray = new boolean[formatList.size()];
254         for (int i = 0; i < formatList.size(); i++) {
255             isFormatSupportedArray[i] =
256                     isFormatSupported(mCodecName, mMediaType, formatList.get(i));
257         }
258         boolean isPass = nativeTestAMediaCodecInfo(mCodecName, codecInfo.isEncoder(), expectedKind,
259                 codecInfo.isVendor(), codecInfo.getCanonicalName(),
260                 getMaxSupportedInstances(mCodecName, mMediaType), getExpectedCodecType(mCodecName),
261                 mMediaType, features, featureSupportMap, featureRequiredMap, files,
262                 isFormatSupportedArray, mTestResults);
263         Assert.assertTrue(mTestResults.toString(), isPass);
264     }
265 
nativeTestAMediaCodecInfo(String codecName, boolean isEncoder, int codecKind, boolean isVendor, String canonicalName, int maxSupportedInstances, int codecType, String mediaType, String[] features, int featureSupportMap, int featureRequiredMap, String[] files, boolean[] isFormatSupported, StringBuilder retMsg)266     private native boolean nativeTestAMediaCodecInfo(String codecName, boolean isEncoder,
267             int codecKind, boolean isVendor, String canonicalName, int maxSupportedInstances,
268             int codecType, String mediaType, String[] features, int featureSupportMap,
269             int featureRequiredMap, String[] files, boolean[] isFormatSupported,
270             StringBuilder retMsg);
271 
272     @ApiTest(apis = {"AMediaCodecInfo_getVideoCapabilities",
273             "ACodecVideoCapabilities_getBitrateRange",
274             "ACodecVideoCapabilities_getSupportedWidths",
275             "ACodecVideoCapabilities_getSupportedHeights",
276             "ACodecVideoCapabilities_getSupportedFrameRates",
277             "ACodecVideoCapabilities_getWidthAlignment",
278             "ACodecVideoCapabilities_getHeightAlignment",
279             "ACodecEncoderCapabilities_isBitrateModeSupported",
280             "ACodecEncoderCapabilities_getComplexityRange",
281             "ACodecEncoderCapabilities_getQualityRange"})
282     @SmallTest
283     @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
testAMediaCodecInfoGetVideoCapabilitiesNative()284     public void testAMediaCodecInfoGetVideoCapabilitiesNative() {
285         Assume.assumeTrue("Test is applicable for video codecs",
286                 mMediaType.startsWith("video/") || mMediaType.equalsIgnoreCase(
287                         MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC));
288         MediaCodecInfo codecInfo = getCodecInfo(mCodecName);
289         Assert.assertNotNull("received null codecInfo for component: " + mCodecName, codecInfo);
290         MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(mMediaType);
291         MediaCodecInfo.VideoCapabilities videoCaps = caps.getVideoCapabilities();
292         Assert.assertNotNull("received null for video capabilities", videoCaps);
293         boolean isPass = nativeTestAMediaCodecInfoVideoCaps(mCodecName,
294                 videoCaps.getBitrateRange().getLower(), videoCaps.getBitrateRange().getUpper(),
295                 videoCaps.getSupportedWidths().getLower(),
296                 videoCaps.getSupportedWidths().getUpper(),
297                 videoCaps.getSupportedHeights().getLower(),
298                 videoCaps.getSupportedHeights().getUpper(),
299                 videoCaps.getSupportedFrameRates().getLower(),
300                 videoCaps.getSupportedFrameRates().getUpper(), videoCaps.getWidthAlignment(),
301                 videoCaps.getHeightAlignment(),
302                 mTestResults);
303         Assert.assertTrue(mTestResults.toString(), isPass);
304         MediaCodecInfo.EncoderCapabilities encCaps = caps.getEncoderCapabilities();
305         if (codecInfo.isEncoder()) {
306             Assert.assertNotNull("received null for encoder capabilities", encCaps);
307             int bitrateModeSupportMap = 0;
308             for (int i = 0; i < 4; i++) {
309                 if (encCaps.isBitrateModeSupported(i)) {
310                     bitrateModeSupportMap |= (1 << i);
311                 }
312             }
313             isPass = nativeTestAMediaCodecInfoGetEncoderCapabilities(mCodecName,
314                     encCaps.getComplexityRange().getLower(),
315                     encCaps.getComplexityRange().getUpper(),
316                     encCaps.getQualityRange().getLower(), encCaps.getQualityRange().getUpper(),
317                     bitrateModeSupportMap,
318                     mTestResults);
319             Assert.assertTrue(mTestResults.toString(), isPass);
320         }
321     }
322 
nativeTestAMediaCodecInfoVideoCaps(String codecName, int bitRateRangeLower, int bitRateRangeUpper, int supportedWidthLower, int supportedWidthUpper, int supportHeightLower, int supportedHeightUpper, int supportedFrameRateLower, int supportedFrameRateUpper, int widthAlignment, int heightAlignment, StringBuilder retMsg)323     private native boolean nativeTestAMediaCodecInfoVideoCaps(String codecName,
324             int bitRateRangeLower, int bitRateRangeUpper, int supportedWidthLower,
325             int supportedWidthUpper, int supportHeightLower, int supportedHeightUpper,
326             int supportedFrameRateLower, int supportedFrameRateUpper, int widthAlignment,
327             int heightAlignment, StringBuilder retMsg);
328 
nativeTestAMediaCodecInfoGetEncoderCapabilities(String codecName, int complexityRangeLower, int complexityRangeUpper, int qualityRangeLower, int qualityRangeUpper, int bitrateModeSupportMap, StringBuilder retMsg)329     private native boolean nativeTestAMediaCodecInfoGetEncoderCapabilities(String codecName,
330             int complexityRangeLower, int complexityRangeUpper, int qualityRangeLower,
331             int qualityRangeUpper, int bitrateModeSupportMap, StringBuilder retMsg);
332 
333     @ApiTest(apis = {"ACodecVideoCapabilities_getSupportedWidthsFor",
334             "ACodecVideoCapabilities_getSupportedHeightsFor",
335             "ACodecVideoCapabilities_getSupportedFrameRatesFor",
336             "ACodecVideoCapabilities_getAchievableFrameRatesFor",
337             "ACodecVideoCapabilities_areSizeAndRateSupported",
338             "ACodecVideoCapabilities_isSizeSupported"})
339     @SmallTest
340     @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
testAMediaCodecInfoGetVideoCapsGetSupportForNative()341     public void testAMediaCodecInfoGetVideoCapsGetSupportForNative() {
342         Assume.assumeTrue("Test is applicable for video codecs",
343                 mMediaType.startsWith("video/") || mMediaType.equalsIgnoreCase(
344                         MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC));
345         MediaCodecInfo codecInfo = getCodecInfo(mCodecName);
346         Assert.assertNotNull("received null codecInfo for component: " + mCodecName, codecInfo);
347         MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(mMediaType);
348         MediaCodecInfo.VideoCapabilities videoCaps = caps.getVideoCapabilities();
349         Assert.assertNotNull("received null for video capabilities", videoCaps);
350         for (double frameRate : STANDARD_FPS) {
351             for (Size res : STANDARD_RES) {
352                 for (boolean isLandscape : new boolean[]{true, false}) {
353                     int width = isLandscape ? res.getWidth() : res.getHeight();
354                     int height = isLandscape ? res.getHeight() : res.getWidth();
355                     Range<Integer> widths = getSupportedWidthsForNoExcep(videoCaps, height);
356                     Range<Integer> heights = getSupportedHeightsForNoExcep(videoCaps, width);
357                     Range<Double> supportedRates =
358                             getSupportedFrameRatesForNoExcep(videoCaps, width, height);
359                     Range<Double> achievableRates =
360                             getAchievableFrameRatesForNoExcep(videoCaps, width, height);
361                     boolean isPass =
362                             nativeTestAMediaCodecInfoVideoCapsGetSupportFor(mCodecName, width,
363                                     height, frameRate, widths.getLower(), widths.getUpper(),
364                                     heights.getLower(), heights.getUpper(),
365                                     supportedRates.getLower(), supportedRates.getUpper(),
366                                     achievableRates.getLower(), achievableRates.getUpper(),
367                                     videoCaps.isSizeSupported(width, height),
368                                     videoCaps.areSizeAndRateSupported(width, height, frameRate),
369                                     mTestResults);
370                     Assert.assertTrue(mTestResults.toString(), isPass);
371                 }
372             }
373         }
374     }
375 
nativeTestAMediaCodecInfoVideoCapsGetSupportFor(String codecName, int testWidth, int testHeight, double frameRate, int supportedWidthLowerForHeight, int supportedWidthUpperForHeight, int supportedHeightLowerForWidth, int supportedHeightUpperForWidth, double supportedFrameRateLower, double supportedFrameRateUpper, double achievedFrameRateLower, double achievedFrameRateUpper, boolean isSizeSupported, boolean areSizeAndRateSupported, StringBuilder retMsg)376     private native boolean nativeTestAMediaCodecInfoVideoCapsGetSupportFor(String codecName,
377             int testWidth, int testHeight, double frameRate, int supportedWidthLowerForHeight,
378             int supportedWidthUpperForHeight, int supportedHeightLowerForWidth,
379             int supportedHeightUpperForWidth, double supportedFrameRateLower,
380             double supportedFrameRateUpper, double achievedFrameRateLower,
381             double achievedFrameRateUpper, boolean isSizeSupported, boolean areSizeAndRateSupported,
382             StringBuilder retMsg);
383 
384     @ApiTest(apis = {"ACodecPerformancePoint_create",
385             "ACodecPerformancePoint_coversFormat",
386             "ACodecPerformancePoint_covers",
387             "ACodecPerformancePoint_equals"})
388     @SmallTest
389     @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
testAMediaCodecInfoGetPerformancePointNative()390     public void testAMediaCodecInfoGetPerformancePointNative() {
391         Assume.assumeTrue("Test is applicable for video codecs",
392                 mMediaType.startsWith("video/") || mMediaType.equalsIgnoreCase(
393                         MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC));
394         MediaCodecInfo codecInfo = getCodecInfo(mCodecName);
395         Assert.assertNotNull("received null codecInfo for component: " + mCodecName, codecInfo);
396         MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(mMediaType);
397         MediaCodecInfo.VideoCapabilities videoCaps = caps.getVideoCapabilities();
398         Assert.assertNotNull("received null for video capabilities", videoCaps);
399         List<MediaCodecInfo.VideoCapabilities.PerformancePoint> ppList =
400                 videoCaps.getSupportedPerformancePoints();
401         int listSize = ppList != null ? ppList.size() : 0;
402         for (double frameRate : STANDARD_FPS) {
403             for (Size res : STANDARD_RES) {
404                 int width = res.getWidth();
405                 int height = res.getHeight();
406                 int coversFormat = 0;
407                 int coversPoint = 0;
408                 int equalsPoint = 0;
409                 if (listSize != 0) {
410                     MediaFormat format = MediaFormat.createVideoFormat(mMediaType, width, height);
411                     format.setFloat(MediaFormat.KEY_FRAME_RATE, (float) frameRate);
412                     MediaCodecInfo.VideoCapabilities.PerformancePoint point =
413                             new MediaCodecInfo.VideoCapabilities.PerformancePoint(width, height,
414                                     (int) frameRate);
415                     for (int i = 0; i < listSize; i++) {
416                         MediaCodecInfo.VideoCapabilities.PerformancePoint pp = ppList.get(i);
417                         if (pp.covers(format)) {
418                             coversFormat |= (1 << i);
419                         }
420                         if (pp.covers(point)) {
421                             coversPoint |= (1 << i);
422                         }
423                         if (pp.equals(point)) {
424                             equalsPoint |= (1 << i);
425                         }
426                     }
427                 }
428                 boolean isPass =
429                         nativeTestACodecPerformancePoint(mCodecName, width, height, frameRate,
430                                 coversFormat, coversPoint, equalsPoint, listSize, mTestResults);
431                 Assert.assertTrue(mTestResults.toString(), isPass);
432                 if (listSize == 0) return;
433             }
434         }
435     }
436 
nativeTestACodecPerformancePoint(String codecName, int width, int height, double frameRate, int coversFormat, int coversPoint, int equalsPoint, int ppSize, StringBuilder retMsg)437     private native boolean nativeTestACodecPerformancePoint(String codecName, int width, int height,
438             double frameRate, int coversFormat, int coversPoint, int equalsPoint, int ppSize,
439             StringBuilder retMsg);
440 
441     @ApiTest(apis = {"ACodecAudioCapabilities_getBitrateRange",
442             "ACodecAudioCapabilities_getMaxInputChannelCount",
443             "ACodecAudioCapabilities_getMinInputChannelCount",
444             "ACodecAudioCapabilities_getSupportedSampleRates",
445             "ACodecAudioCapabilities_getSupportedSampleRateRanges",
446             "ACodecAudioCapabilities_getInputChannelCountRanges",
447             "ACodecEncoderCapabilities_isBitrateModeSupported",
448             "ACodecEncoderCapabilities_getComplexityRange",
449             "ACodecEncoderCapabilities_getQualityRange"})
450     @SmallTest
451     @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
testAMediaCodecInfoGetAudioCapabilitiesNative()452     public void testAMediaCodecInfoGetAudioCapabilitiesNative() {
453         Assume.assumeTrue("Test is applicable for audio codecs", mMediaType.startsWith("audio/"));
454         MediaCodecInfo codecInfo = getCodecInfo(mCodecName);
455         Assert.assertNotNull("received null codecInfo for component: " + mCodecName, codecInfo);
456         MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(mMediaType);
457         MediaCodecInfo.AudioCapabilities audioCaps = caps.getAudioCapabilities();
458         Assert.assertNotNull("received null for audio capabilities", audioCaps);
459         int[] sampleRates = audioCaps.getSupportedSampleRates();
460         int[] sampleRateRanges = new int[audioCaps.getSupportedSampleRateRanges().length * 2];
461         int i = 0;
462         for (Range<Integer> range : audioCaps.getSupportedSampleRateRanges()) {
463             sampleRateRanges[i++] = range.getLower();
464             sampleRateRanges[i++] = range.getUpper();
465         }
466         Range<Integer>[] channelRanges = audioCaps.getInputChannelCountRanges();
467         int[] inputChannelRanges = new int[channelRanges.length * 2];
468         int j = 0;
469         for (Range<Integer> range : channelRanges) {
470             inputChannelRanges[j++] = range.getLower();
471             inputChannelRanges[j++] = range.getUpper();
472         }
473         int[] standardSampleRates =
474                 new int[]{8000, 11025, 12000, 16000, 22050, 24000, 44100, 48000, 88200, 96000,
475                         192000};
476         int standardSampleRatesSupportMap = 0;
477         for (i = 0; i < standardSampleRates.length; i++) {
478             if (audioCaps.isSampleRateSupported(standardSampleRates[i])) {
479                 standardSampleRatesSupportMap |= (1 << i);
480             }
481         }
482         boolean isPass = nativeTestAMediaCodecInfoGetAudioCapabilities(mCodecName,
483                 audioCaps.getBitrateRange().getLower(), audioCaps.getBitrateRange().getUpper(),
484                 audioCaps.getMaxInputChannelCount(), audioCaps.getMinInputChannelCount(),
485                 sampleRates, sampleRateRanges, inputChannelRanges, standardSampleRates,
486                 standardSampleRatesSupportMap, mTestResults);
487         Assert.assertTrue(mTestResults.toString(), isPass);
488 
489         MediaCodecInfo.EncoderCapabilities encCaps = caps.getEncoderCapabilities();
490         if (codecInfo.isEncoder()) {
491             Assert.assertNotNull("received null for encoder capabilities", encCaps);
492             int bitrateModeSupportMap = 0;
493             for (i = BITRATE_MODE_CQ; i <= BITRATE_MODE_CBR_FD; i++) {
494                 if (encCaps.isBitrateModeSupported(i)) {
495                     bitrateModeSupportMap |= (1 << i);
496                 }
497             }
498             isPass = nativeTestAMediaCodecInfoGetEncoderCapabilities(mCodecName,
499                     encCaps.getComplexityRange().getLower(),
500                     encCaps.getComplexityRange().getUpper(),
501                     encCaps.getQualityRange().getLower(), encCaps.getQualityRange().getUpper(),
502                     bitrateModeSupportMap,
503                     mTestResults);
504             Assert.assertTrue(mTestResults.toString(), isPass);
505         }
506     }
507 
nativeTestAMediaCodecInfoGetAudioCapabilities(String codecName, int mLower, int mUpper, int maxInputChannelCount, int minInputChannelCount, int[] sampleRates, int[] sampleRateRanges, int[] inputChannelRanges, int[] standardSampleRates, int standardSampleRatesSupportMap, StringBuilder retMsg)508     private native boolean nativeTestAMediaCodecInfoGetAudioCapabilities(String codecName,
509             int mLower, int mUpper, int maxInputChannelCount, int minInputChannelCount,
510             int[] sampleRates, int[] sampleRateRanges, int[] inputChannelRanges,
511             int[] standardSampleRates, int standardSampleRatesSupportMap, StringBuilder retMsg);
512 }
513