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