1 /* 2 * Copyright (C) 2020 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 android.media.MediaCodec; 20 import android.media.MediaCodecInfo; 21 import android.media.MediaExtractor; 22 import android.media.MediaFormat; 23 import android.media.MediaMuxer; 24 import android.util.Log; 25 import android.util.Pair; 26 27 import org.junit.Assume; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.Parameterized; 31 32 import java.io.File; 33 import java.io.IOException; 34 import java.nio.ByteBuffer; 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 import java.util.Collection; 38 import java.util.HashMap; 39 import java.util.List; 40 41 import static android.media.MediaCodecInfo.CodecProfileLevel.*; 42 import static org.junit.Assert.assertEquals; 43 import static org.junit.Assert.assertFalse; 44 import static org.junit.Assert.assertTrue; 45 import static org.junit.Assert.fail; 46 47 /** 48 * Validate profile and level configuration for listed encoder components 49 */ 50 @RunWith(Parameterized.class) 51 public class EncoderProfileLevelTest extends CodecEncoderTestBase { 52 private static final String LOG_TAG = EncoderProfileLevelTest.class.getSimpleName(); 53 private static final HashMap<String, int[]> mProfileMap = new HashMap<>(); 54 private static final HashMap<String, Pair<int[], Integer>> mProfileLevelCdd = new HashMap<>(); 55 56 private MediaFormat mConfigFormat; 57 private MediaMuxer mMuxer; 58 EncoderProfileLevelTest(String encoder, String mime, int bitrate, int encoderInfo1, int encoderInfo2, int frameRate)59 public EncoderProfileLevelTest(String encoder, String mime, int bitrate, int encoderInfo1, 60 int encoderInfo2, int frameRate) { 61 super(encoder, mime, new int[]{bitrate}, new int[]{encoderInfo1}, new int[]{encoderInfo2}); 62 if (mIsAudio) { 63 mSampleRate = encoderInfo1; 64 mChannels = encoderInfo2; 65 } else { 66 mWidth = encoderInfo1; 67 mHeight = encoderInfo2; 68 mFrameRate = frameRate; 69 } 70 setUpParams(1); 71 mConfigFormat = mFormats.get(0); 72 } 73 74 @Parameterized.Parameters(name = "{index}({0}_{1})") input()75 public static Collection<Object[]> input() { 76 final boolean isEncoder = true; 77 final boolean needAudio = true; 78 final boolean needVideo = true; 79 final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{ 80 // Audio - CodecMime, bit-rate, sample rate, channel count 81 {MediaFormat.MIMETYPE_AUDIO_AAC, 64000, 48000, 1, -1}, 82 {MediaFormat.MIMETYPE_AUDIO_AAC, 128000, 48000, 2, -1}, 83 84 // Video - CodecMime, bit-rate, height, width, frame-rate 85 // TODO (b/151423508) 86 /*{MediaFormat.MIMETYPE_VIDEO_AVC, 64000, 176, 144, 15}, 87 {MediaFormat.MIMETYPE_VIDEO_AVC, 128000, 176, 144, 15}, 88 {MediaFormat.MIMETYPE_VIDEO_AVC, 192000, 352, 288, 7}, 89 {MediaFormat.MIMETYPE_VIDEO_AVC, 384000, 352, 288, 15},*/ 90 {MediaFormat.MIMETYPE_VIDEO_AVC, 768000, 352, 288, 30}, 91 {MediaFormat.MIMETYPE_VIDEO_AVC, 2000000, 352, 288, 30}, 92 // TODO (b/151423508) 93 /*{MediaFormat.MIMETYPE_VIDEO_AVC, 4000000, 352, 576, 25}, 94 {MediaFormat.MIMETYPE_VIDEO_AVC, 4000000, 720, 576, 12}, 95 {MediaFormat.MIMETYPE_VIDEO_AVC, 10000000, 720, 576, 25},*/ 96 {MediaFormat.MIMETYPE_VIDEO_AVC, 14000000, 1280, 720, 30}, 97 {MediaFormat.MIMETYPE_VIDEO_AVC, 20000000, 1280, 1024, 42}, 98 {MediaFormat.MIMETYPE_VIDEO_AVC, 20000000, 2048, 1024, 30}, 99 {MediaFormat.MIMETYPE_VIDEO_AVC, 50000000, 2048, 1024, 30}, 100 {MediaFormat.MIMETYPE_VIDEO_AVC, 50000000, 2048, 1080, 60}, 101 {MediaFormat.MIMETYPE_VIDEO_AVC, 135000000, 3672, 1536, 25}, 102 {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 4096, 2304, 25}, 103 {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 4096, 2304, 50}, 104 {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 8192, 4320, 30}, 105 {MediaFormat.MIMETYPE_VIDEO_AVC, 480000000, 8192, 4320, 60}, 106 {MediaFormat.MIMETYPE_VIDEO_AVC, 800000000, 8192, 4320, 120}, 107 108 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 4000000, 352, 288, 30}, 109 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 15000000, 720, 576, 30}, 110 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 60000000, 1440, 1088, 60}, 111 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 80000000, 1920, 1088, 60}, 112 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 80000000, 1920, 1088, 60}, 113 114 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 64000, 176, 144, 15}, 115 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 64000, 176, 144, 30}, 116 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 176, 144, 15}, 117 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 352, 288, 30}, 118 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 384000, 352, 288, 30}, 119 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 4000000, 640, 480, 30}, 120 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 8000000, 720, 576, 30}, 121 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 12000000, 1280, 720, 30}, 122 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 176, 144, 30}, 123 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 384000, 352, 288, 30}, 124 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 768000, 352, 288, 30}, 125 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 1500000, 352, 288, 30}, 126 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 3000000, 704, 576, 30}, 127 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 8000000, 720, 576, 30}, 128 129 // TODO (b/151430764) 130 /*{MediaFormat.MIMETYPE_VIDEO_VP9, 200000, 256, 144, 15}, 131 {MediaFormat.MIMETYPE_VIDEO_VP9, 8000000, 384, 192, 30}, 132 {MediaFormat.MIMETYPE_VIDEO_VP9, 1800000, 480, 256, 30}, 133 {MediaFormat.MIMETYPE_VIDEO_VP9, 3600000, 640, 384, 30}, 134 {MediaFormat.MIMETYPE_VIDEO_VP9, 7200000, 1080, 512, 30},*/ 135 {MediaFormat.MIMETYPE_VIDEO_VP9, 12000000, 1280, 768, 30}, 136 {MediaFormat.MIMETYPE_VIDEO_VP9, 18000000, 2048, 1088, 30}, 137 {MediaFormat.MIMETYPE_VIDEO_VP9, 30000000, 2048, 1088, 60}, 138 {MediaFormat.MIMETYPE_VIDEO_VP9, 60000000, 4096, 2176, 30}, 139 {MediaFormat.MIMETYPE_VIDEO_VP9, 120000000, 4096, 2176, 60}, 140 {MediaFormat.MIMETYPE_VIDEO_VP9, 180000000, 4096, 2176, 120}, 141 {MediaFormat.MIMETYPE_VIDEO_VP9, 180000000, 8192, 4352, 30}, 142 {MediaFormat.MIMETYPE_VIDEO_VP9, 240000000, 8192, 4352, 60}, 143 {MediaFormat.MIMETYPE_VIDEO_VP9, 480000000, 8192, 4352, 120}, 144 145 {MediaFormat.MIMETYPE_VIDEO_H263, 64000, 176, 144, 15}, 146 {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 176, 144, 15}, 147 {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 176, 144, 30}, 148 {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 352, 288, 15}, 149 {MediaFormat.MIMETYPE_VIDEO_H263, 384000, 352, 288, 30}, 150 {MediaFormat.MIMETYPE_VIDEO_H263, 2048000, 352, 288, 30}, 151 {MediaFormat.MIMETYPE_VIDEO_H263, 4096000, 352, 240, 60}, 152 {MediaFormat.MIMETYPE_VIDEO_H263, 4096000, 352, 288, 50}, 153 {MediaFormat.MIMETYPE_VIDEO_H263, 8192000, 720, 240, 60}, 154 {MediaFormat.MIMETYPE_VIDEO_H263, 8192000, 720, 288, 50}, 155 {MediaFormat.MIMETYPE_VIDEO_H263, 16384000, 720, 480, 60}, 156 {MediaFormat.MIMETYPE_VIDEO_H263, 16384000, 720, 576, 50}, 157 158 // TODO (b/151429828) 159 //{MediaFormat.MIMETYPE_VIDEO_HEVC, 128000, 176, 144, 15}, 160 {MediaFormat.MIMETYPE_VIDEO_HEVC, 1500000, 352, 288, 30}, 161 // TODO (b/152576008) - Limit HEVC Encoder test to 512x512 162 {MediaFormat.MIMETYPE_VIDEO_HEVC, 3000000, 512, 512, 30}, 163 //{MediaFormat.MIMETYPE_VIDEO_HEVC, 3000000, 640, 360, 30}, 164 //{MediaFormat.MIMETYPE_VIDEO_HEVC, 6000000, 960, 540, 30}, 165 {MediaFormat.MIMETYPE_VIDEO_HEVC, 10000000, 1280, 720, 33}, 166 {MediaFormat.MIMETYPE_VIDEO_HEVC, 12000000, 2048, 1080, 30}, 167 {MediaFormat.MIMETYPE_VIDEO_HEVC, 20000000, 2048, 1080, 60}, 168 {MediaFormat.MIMETYPE_VIDEO_HEVC, 25000000, 4096, 2160, 30}, 169 {MediaFormat.MIMETYPE_VIDEO_HEVC, 40000000, 4096, 2160, 60}, 170 {MediaFormat.MIMETYPE_VIDEO_HEVC, 60000000, 4096, 2160, 120}, 171 {MediaFormat.MIMETYPE_VIDEO_HEVC, 60000000, 8192, 4320, 30}, 172 {MediaFormat.MIMETYPE_VIDEO_HEVC, 120000000, 8192, 4320, 60}, 173 {MediaFormat.MIMETYPE_VIDEO_HEVC, 240000000, 8192, 4320, 120}, 174 175 {MediaFormat.MIMETYPE_VIDEO_AV1, 1500000, 426, 240, 30}, 176 {MediaFormat.MIMETYPE_VIDEO_AV1, 3000000, 640, 360, 30}, 177 {MediaFormat.MIMETYPE_VIDEO_AV1, 6000000, 854, 480, 30}, 178 {MediaFormat.MIMETYPE_VIDEO_AV1, 10000000, 1280, 720, 30}, 179 {MediaFormat.MIMETYPE_VIDEO_AV1, 12000000, 1920, 1080, 30}, 180 {MediaFormat.MIMETYPE_VIDEO_AV1, 20000000, 1920, 1080, 60}, 181 {MediaFormat.MIMETYPE_VIDEO_AV1, 30000000, 3840, 2160, 30}, 182 {MediaFormat.MIMETYPE_VIDEO_AV1, 40000000, 3840, 2160, 60}, 183 {MediaFormat.MIMETYPE_VIDEO_AV1, 60000000, 3840, 2160, 120}, 184 {MediaFormat.MIMETYPE_VIDEO_AV1, 60000000, 7680, 4320, 30}, 185 {MediaFormat.MIMETYPE_VIDEO_AV1, 100000000, 7680, 4320, 60}, 186 {MediaFormat.MIMETYPE_VIDEO_AV1, 160000000, 7680, 4320, 120}, 187 188 {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 176, 144, 20}, 189 {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 480, 360, 20}, 190 }); 191 return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false); 192 } 193 194 static { mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AVC, new int[]{AVCProfileBaseline, AVCProfileMain, AVCProfileExtended, AVCProfileHigh, AVCProfileHigh10, AVCProfileHigh422, AVCProfileHigh444, AVCProfileConstrainedBaseline, AVCProfileConstrainedHigh})195 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AVC, 196 new int[]{AVCProfileBaseline, AVCProfileMain, AVCProfileExtended, AVCProfileHigh, 197 AVCProfileHigh10, AVCProfileHigh422, AVCProfileHigh444, 198 AVCProfileConstrainedBaseline, AVCProfileConstrainedHigh}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC, new int[]{HEVCProfileMain, HEVCProfileMain10, HEVCProfileMainStill, })199 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC, 200 new int[]{HEVCProfileMain, HEVCProfileMain10, HEVCProfileMainStill, 201 // TODO: test HDR profiles once they are supported by MediaMuxer 202 /* HEVCProfileMain10HDR10, HEVCProfileMain10HDR10Plus */}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_H263, new int[]{H263ProfileBaseline, H263ProfileH320Coding, H263ProfileBackwardCompatible, H263ProfileISWV2, H263ProfileISWV3, H263ProfileHighCompression, H263ProfileInternet, H263ProfileInterlace, H263ProfileHighLatency})203 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_H263, 204 new int[]{H263ProfileBaseline, H263ProfileH320Coding, 205 H263ProfileBackwardCompatible, H263ProfileISWV2, H263ProfileISWV3, 206 H263ProfileHighCompression, H263ProfileInternet, H263ProfileInterlace, 207 H263ProfileHighLatency}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG2, new int[]{MPEG2ProfileSimple, MPEG2ProfileMain, MPEG2Profile422, MPEG2ProfileSNR, MPEG2ProfileSpatial, MPEG2ProfileHigh})208 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG2, 209 new int[]{MPEG2ProfileSimple, MPEG2ProfileMain, MPEG2Profile422, MPEG2ProfileSNR, 210 MPEG2ProfileSpatial, MPEG2ProfileHigh}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG4, new int[]{MPEG4ProfileSimple, MPEG4ProfileSimpleScalable, MPEG4ProfileCore, MPEG4ProfileMain, MPEG4ProfileNbit, MPEG4ProfileScalableTexture, MPEG4ProfileSimpleFace, MPEG4ProfileSimpleFBA, MPEG4ProfileBasicAnimated, MPEG4ProfileHybrid, MPEG4ProfileAdvancedRealTime, MPEG4ProfileCoreScalable, MPEG4ProfileAdvancedCoding, MPEG4ProfileAdvancedCore, MPEG4ProfileAdvancedScalable, MPEG4ProfileAdvancedSimple})211 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG4, 212 new int[]{MPEG4ProfileSimple, MPEG4ProfileSimpleScalable, MPEG4ProfileCore, 213 MPEG4ProfileMain, MPEG4ProfileNbit, MPEG4ProfileScalableTexture, 214 MPEG4ProfileSimpleFace, MPEG4ProfileSimpleFBA, MPEG4ProfileBasicAnimated, 215 MPEG4ProfileHybrid, MPEG4ProfileAdvancedRealTime, 216 MPEG4ProfileCoreScalable, MPEG4ProfileAdvancedCoding, 217 MPEG4ProfileAdvancedCore, MPEG4ProfileAdvancedScalable, 218 MPEG4ProfileAdvancedSimple}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP8, new int[]{VP8ProfileMain})219 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP8, new int[]{VP8ProfileMain}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, new int[]{VP9Profile0, VP9Profile1})220 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, new int[]{VP9Profile0, VP9Profile1}); mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AV1, new int[]{AV1ProfileMain8, AV1ProfileMain10, })221 mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AV1, 222 new int[]{AV1ProfileMain8, AV1ProfileMain10, 223 // TODO: test HDR profiles once they are supported by MediaMuxer 224 /* AV1ProfileMain10HDR10, AV1ProfileMain10HDR10Plus */}); mProfileMap.put(MediaFormat.MIMETYPE_AUDIO_AAC, new int[]{AACObjectMain, AACObjectLC, AACObjectSSR, AACObjectLTP, AACObjectHE, AACObjectScalable, AACObjectERLC, AACObjectERScalable, AACObjectLD, AACObjectELD, AACObjectXHE})225 mProfileMap.put(MediaFormat.MIMETYPE_AUDIO_AAC, 226 new int[]{AACObjectMain, AACObjectLC, AACObjectSSR, AACObjectLTP, AACObjectHE, 227 AACObjectScalable, AACObjectERLC, AACObjectERScalable, AACObjectLD, 228 AACObjectELD, AACObjectXHE}); 229 } 230 231 static { mProfileLevelCdd.put(MediaFormat.MIMETYPE_AUDIO_AAC, new Pair<>(new int[]{AACObjectLC, AACObjectHE, AACObjectELD}, -1))232 mProfileLevelCdd.put(MediaFormat.MIMETYPE_AUDIO_AAC, 233 new Pair<>(new int[]{AACObjectLC, AACObjectHE, AACObjectELD}, -1)); mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_H263, new Pair<>(new int[]{H263ProfileBaseline}, H263Level45))234 mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_H263, 235 new Pair<>(new int[]{H263ProfileBaseline}, H263Level45)); mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_AVC, new Pair<>(new int[]{AVCProfileBaseline}, AVCLevel3))236 mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_AVC, 237 new Pair<>(new int[]{AVCProfileBaseline}, AVCLevel3)); mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_HEVC, new Pair<>(new int[]{HEVCProfileMain}, HEVCMainTierLevel3))238 mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_HEVC, 239 new Pair<>(new int[]{HEVCProfileMain}, HEVCMainTierLevel3)); mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP8, new Pair<>(new int[]{VP8ProfileMain}, VP8Level_Version0))240 mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP8, 241 new Pair<>(new int[]{VP8ProfileMain}, VP8Level_Version0)); mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP9, new Pair<>(new int[]{VP9Profile0}, VP9Level3))242 mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP9, 243 new Pair<>(new int[]{VP9Profile0}, VP9Level3)); 244 } 245 getMinLevel(String mime, int width, int height, int frameRate, int bitrate, int profile)246 private int getMinLevel(String mime, int width, int height, int frameRate, int bitrate, 247 int profile) { 248 switch (mime) { 249 case MediaFormat.MIMETYPE_VIDEO_AVC: 250 return getMinLevelAVC(width, height, frameRate, bitrate); 251 case MediaFormat.MIMETYPE_VIDEO_HEVC: 252 return getMinLevelHEVC(width, height, frameRate, bitrate); 253 case MediaFormat.MIMETYPE_VIDEO_H263: 254 return getMinLevelH263(width, height, frameRate, bitrate); 255 case MediaFormat.MIMETYPE_VIDEO_MPEG2: 256 return getMinLevelMPEG2(width, height, frameRate, bitrate); 257 case MediaFormat.MIMETYPE_VIDEO_MPEG4: 258 return getMinLevelMPEG4(width, height, frameRate, bitrate, profile); 259 // complex features disabled in VP8 Level/Version 0 260 case MediaFormat.MIMETYPE_VIDEO_VP8: 261 return VP8Level_Version0; 262 case MediaFormat.MIMETYPE_VIDEO_VP9: 263 return getMinLevelVP9(width, height, frameRate, bitrate); 264 case MediaFormat.MIMETYPE_VIDEO_AV1: 265 return getMinLevelAV1(width, height, frameRate, bitrate); 266 default: 267 return -1; 268 } 269 } 270 getMinLevelAVC(int width, int height, int frameRate, int bitrate)271 private int getMinLevelAVC(int width, int height, int frameRate, int bitrate) { 272 class LevelLimitAVC { 273 private LevelLimitAVC(int level, int mbsPerSec, long mbs, int bitrate) { 274 this.level = level; 275 this.mbsPerSec = mbsPerSec; 276 this.mbs = mbs; 277 this.bitrate = bitrate; 278 } 279 280 private final int level; 281 private final int mbsPerSec; 282 private final long mbs; 283 private final int bitrate; 284 } 285 LevelLimitAVC[] limitsAVC = { 286 new LevelLimitAVC(AVCLevel1, 1485, 99, 64000), 287 new LevelLimitAVC(AVCLevel1b, 1485, 99, 128000), 288 new LevelLimitAVC(AVCLevel11, 3000, 396, 192000), 289 new LevelLimitAVC(AVCLevel12, 6000, 396, 384000), 290 new LevelLimitAVC(AVCLevel13, 11880, 396, 768000), 291 new LevelLimitAVC(AVCLevel2, 11880, 396, 2000000), 292 new LevelLimitAVC(AVCLevel21, 19800, 792, 4000000), 293 new LevelLimitAVC(AVCLevel22, 20250, 1620, 4000000), 294 new LevelLimitAVC(AVCLevel3, 40500, 1620, 10000000), 295 new LevelLimitAVC(AVCLevel31, 108000, 3600, 14000000), 296 new LevelLimitAVC(AVCLevel32, 216000, 5120, 20000000), 297 new LevelLimitAVC(AVCLevel4, 245760, 8192, 20000000), 298 new LevelLimitAVC(AVCLevel41, 245760, 8192, 50000000), 299 new LevelLimitAVC(AVCLevel42, 522240, 8704, 50000000), 300 new LevelLimitAVC(AVCLevel5, 589824, 22080, 135000000), 301 new LevelLimitAVC(AVCLevel51, 983040, 36864, 240000000), 302 new LevelLimitAVC(AVCLevel52, 2073600, 36864, 240000000), 303 new LevelLimitAVC(AVCLevel6, 4177920, 139264, 240000000), 304 new LevelLimitAVC(AVCLevel61, 8355840, 139264, 480000000), 305 new LevelLimitAVC(AVCLevel62, 16711680, 139264, 800000000), 306 }; 307 long mbs = ((width + 15) / 16) * ((height + 15) / 16); 308 float mbsPerSec = mbs * frameRate; 309 for (LevelLimitAVC levelLimitsAVC : limitsAVC) { 310 if (mbs <= levelLimitsAVC.mbs && mbsPerSec <= levelLimitsAVC.mbsPerSec 311 && bitrate <= levelLimitsAVC.bitrate) { 312 return levelLimitsAVC.level; 313 } 314 } 315 // if none of the levels suffice, select the highest level 316 return AVCLevel62; 317 } 318 getMinLevelHEVC(int width, int height, int frameRate, int bitrate)319 private int getMinLevelHEVC(int width, int height, int frameRate, int bitrate) { 320 class LevelLimitHEVC { 321 private LevelLimitHEVC(int level, int frameRate, long samples, int bitrate) { 322 this.level = level; 323 this.frameRate = frameRate; 324 this.samples = samples; 325 this.bitrate = bitrate; 326 } 327 328 private final int level; 329 private final int frameRate; 330 private final long samples; 331 private final int bitrate; 332 } 333 LevelLimitHEVC[] limitsHEVC = { 334 new LevelLimitHEVC(HEVCMainTierLevel1, 15, 36864, 128000), 335 new LevelLimitHEVC(HEVCMainTierLevel2, 30, 122880, 1500000), 336 new LevelLimitHEVC(HEVCMainTierLevel21, 30, 245760, 3000000), 337 new LevelLimitHEVC(HEVCMainTierLevel3, 30, 552960, 6000000), 338 new LevelLimitHEVC(HEVCMainTierLevel31, 30, 983040, 10000000), 339 new LevelLimitHEVC(HEVCMainTierLevel4, 30, 2228224, 12000000), 340 new LevelLimitHEVC(HEVCHighTierLevel4, 30, 2228224, 30000000), 341 new LevelLimitHEVC(HEVCMainTierLevel41, 60, 2228224, 20000000), 342 new LevelLimitHEVC(HEVCHighTierLevel41, 60, 2228224, 50000000), 343 new LevelLimitHEVC(HEVCMainTierLevel5, 30, 8912896, 25000000), 344 new LevelLimitHEVC(HEVCHighTierLevel5, 30, 8912896, 100000000), 345 new LevelLimitHEVC(HEVCMainTierLevel51, 60, 8912896, 40000000), 346 new LevelLimitHEVC(HEVCHighTierLevel51, 60, 8912896, 160000000), 347 new LevelLimitHEVC(HEVCMainTierLevel52, 120, 8912896, 60000000), 348 new LevelLimitHEVC(HEVCHighTierLevel52, 120, 8912896, 240000000), 349 new LevelLimitHEVC(HEVCMainTierLevel6, 30, 35651584, 60000000), 350 new LevelLimitHEVC(HEVCHighTierLevel6, 30, 35651584, 240000000), 351 new LevelLimitHEVC(HEVCMainTierLevel61, 60, 35651584, 120000000), 352 new LevelLimitHEVC(HEVCHighTierLevel61, 60, 35651584, 480000000), 353 new LevelLimitHEVC(HEVCMainTierLevel62, 120, 35651584, 240000000), 354 new LevelLimitHEVC(HEVCHighTierLevel62, 120, 35651584, 800000000), 355 }; 356 long samples = width * height; 357 for (LevelLimitHEVC levelLimitsHEVC : limitsHEVC) { 358 if (samples <= levelLimitsHEVC.samples && frameRate <= levelLimitsHEVC.frameRate 359 && bitrate <= levelLimitsHEVC.bitrate) { 360 return levelLimitsHEVC.level; 361 } 362 } 363 // if none of the levels suffice, select the highest level 364 return HEVCHighTierLevel62; 365 } 366 getMinLevelH263(int width, int height, int frameRate, int bitrate)367 private int getMinLevelH263(int width, int height, int frameRate, int bitrate) { 368 class LevelLimitH263 { 369 private LevelLimitH263(int level, int height, int width, int frameRate, 370 int bitrate) { 371 this.level = level; 372 this.height = height; 373 this.width = width; 374 this.frameRate = frameRate; 375 this.bitrate = bitrate; 376 } 377 378 private final int level; 379 private final int height; 380 private final int width; 381 private final int frameRate; 382 private final int bitrate; 383 } 384 LevelLimitH263[] limitsH263 = { 385 new LevelLimitH263(H263Level10, 176, 144, 15, 64000), 386 new LevelLimitH263(H263Level45, 176, 144, 15, 128000), 387 new LevelLimitH263(H263Level20, 176, 144, 30, 128000), 388 new LevelLimitH263(H263Level20, 352, 288, 15, 128000), 389 new LevelLimitH263(H263Level30, 352, 288, 30, 384000), 390 new LevelLimitH263(H263Level40, 352, 288, 30, 2048000), 391 new LevelLimitH263(H263Level50, 352, 240, 60, 4096000), 392 new LevelLimitH263(H263Level50, 352, 288, 50, 4096000), 393 new LevelLimitH263(H263Level60, 720, 240, 60, 8192000), 394 new LevelLimitH263(H263Level60, 720, 288, 50, 8192000), 395 new LevelLimitH263(H263Level70, 720, 480, 60, 16384000), 396 new LevelLimitH263(H263Level70, 720, 576, 50, 16384000), 397 }; 398 for (LevelLimitH263 levelLimitsH263 : limitsH263) { 399 if (height <= levelLimitsH263.height && width <= levelLimitsH263.width && 400 frameRate <= levelLimitsH263.frameRate && bitrate <= levelLimitsH263.bitrate) { 401 return levelLimitsH263.level; 402 } 403 } 404 // if none of the levels suffice, select the highest level 405 return H263Level70; 406 } 407 getMinLevelVP9(int width, int height, int frameRate, int bitrate)408 private int getMinLevelVP9(int width, int height, int frameRate, int bitrate) { 409 class LevelLimitVP9 { 410 private LevelLimitVP9(int level, long sampleRate, int size, int breadth, 411 int bitrate) { 412 this.level = level; 413 this.sampleRate = sampleRate; 414 this.size = size; 415 this.breadth = breadth; 416 this.bitrate = bitrate; 417 } 418 419 private final int level; 420 private final long sampleRate; 421 private final int size; 422 private final int breadth; 423 private final int bitrate; 424 } 425 LevelLimitVP9[] limitsVP9 = { 426 new LevelLimitVP9(VP9Level1, 829440, 36864, 512, 200000), 427 new LevelLimitVP9(VP9Level11, 2764800, 73728, 768, 800000), 428 new LevelLimitVP9(VP9Level2, 4608000, 122880, 960, 1800000), 429 new LevelLimitVP9(VP9Level21, 9216000, 245760, 1344, 3600000), 430 new LevelLimitVP9(VP9Level3, 20736000, 552960, 2048, 7200000), 431 new LevelLimitVP9(VP9Level31, 36864000, 983040, 2752, 12000000), 432 new LevelLimitVP9(VP9Level4, 83558400, 2228224, 4160, 18000000), 433 new LevelLimitVP9(VP9Level41, 160432128, 2228224, 4160, 30000000), 434 new LevelLimitVP9(VP9Level5, 311951360, 8912896, 8384, 60000000), 435 new LevelLimitVP9(VP9Level51, 588251136, 8912896, 8384, 120000000), 436 new LevelLimitVP9(VP9Level52, 1176502272, 8912896, 8384, 180000000), 437 new LevelLimitVP9(VP9Level6, 1176502272, 35651584, 16832, 180000000), 438 new LevelLimitVP9(VP9Level61, 2353004544L, 35651584, 16832, 240000000), 439 new LevelLimitVP9(VP9Level62, 4706009088L, 35651584, 16832, 480000000), 440 }; 441 int size = width * height; 442 int sampleRate = size * frameRate; 443 int breadth = Math.max(width, height); 444 for (LevelLimitVP9 levelLimitsVP9 : limitsVP9) { 445 if (sampleRate <= levelLimitsVP9.sampleRate && size <= levelLimitsVP9.size && 446 breadth <= levelLimitsVP9.breadth && bitrate <= levelLimitsVP9.bitrate) { 447 return levelLimitsVP9.level; 448 } 449 } 450 // if none of the levels suffice, select the highest level 451 return VP9Level62; 452 } 453 getMinLevelMPEG2(int width, int height, int frameRate, int bitrate)454 private int getMinLevelMPEG2(int width, int height, int frameRate, int bitrate) { 455 class LevelLimitMPEG2 { 456 private LevelLimitMPEG2(int level, long sampleRate, int width, int height, 457 int frameRate, int bitrate) { 458 this.level = level; 459 this.sampleRate = sampleRate; 460 this.width = width; 461 this.height = height; 462 this.frameRate = frameRate; 463 this.bitrate = bitrate; 464 } 465 466 private final int level; 467 private final long sampleRate; 468 private final int width; 469 private final int height; 470 private final int frameRate; 471 private final int bitrate; 472 } 473 // main profile limits, higher profiles will also support selected level 474 LevelLimitMPEG2[] limitsMPEG2 = { 475 new LevelLimitMPEG2(MPEG2LevelLL, 3041280, 352, 288, 30, 4000000), 476 new LevelLimitMPEG2(MPEG2LevelML, 10368000, 720, 576, 30, 15000000), 477 new LevelLimitMPEG2(MPEG2LevelH14, 47001600, 1440, 1088, 60, 60000000), 478 new LevelLimitMPEG2(MPEG2LevelHL, 62668800, 1920, 1088, 60, 80000000), 479 new LevelLimitMPEG2(MPEG2LevelHP, 125337600, 1920, 1088, 60, 80000000), 480 }; 481 int size = width * height; 482 int sampleRate = size * frameRate; 483 for (LevelLimitMPEG2 levelLimitsMPEG2 : limitsMPEG2) { 484 if (sampleRate <= levelLimitsMPEG2.sampleRate && width <= levelLimitsMPEG2.width && 485 height <= levelLimitsMPEG2.height && frameRate <= levelLimitsMPEG2.frameRate && 486 bitrate <= levelLimitsMPEG2.bitrate) { 487 return levelLimitsMPEG2.level; 488 } 489 } 490 // if none of the levels suffice, select the highest level 491 return MPEG2LevelHP; 492 } 493 getMinLevelMPEG4(int width, int height, int frameRate, int bitrate, int profile)494 private int getMinLevelMPEG4(int width, int height, int frameRate, int bitrate, int profile) { 495 class LevelLimitMPEG4 { 496 private LevelLimitMPEG4(int profile, int level, long sampleRate, int width, 497 int height, int frameRate, int bitrate) { 498 this.profile = profile; 499 this.level = level; 500 this.sampleRate = sampleRate; 501 this.width = width; 502 this.height = height; 503 this.frameRate = frameRate; 504 this.bitrate = bitrate; 505 } 506 507 private final int profile; 508 private final int level; 509 private final long sampleRate; 510 private final int width; 511 private final int height; 512 private final int frameRate; 513 private final int bitrate; 514 } 515 // simple profile limits, higher profiles will also support selected level 516 LevelLimitMPEG4[] limitsMPEG4 = { 517 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0, 380160, 176, 144, 15, 64000), 518 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level1, 380160, 176, 144, 30, 64000), 519 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0b, 380160, 176, 144, 15, 128000), 520 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level2, 1520640, 352, 288, 30, 128000), 521 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level3, 3041280, 352, 288, 30, 384000), 522 new LevelLimitMPEG4( 523 MPEG4ProfileSimple, MPEG4Level4a, 9216000, 640, 480, 30, 4000000), 524 new LevelLimitMPEG4( 525 MPEG4ProfileSimple, MPEG4Level5, 10368000, 720, 576, 30, 8000000), 526 new LevelLimitMPEG4( 527 MPEG4ProfileSimple, MPEG4Level6, 27648000, 1280, 720, 30, 12000000), 528 new LevelLimitMPEG4( 529 MPEG4ProfileAdvancedSimple, MPEG4Level1, 760320, 176, 144, 30, 128000), 530 new LevelLimitMPEG4( 531 MPEG4ProfileAdvancedSimple, MPEG4Level2, 1520640, 352, 288, 30, 384000), 532 new LevelLimitMPEG4( 533 MPEG4ProfileAdvancedSimple, MPEG4Level3, 3041280, 352, 288, 30, 768000), 534 new LevelLimitMPEG4( 535 MPEG4ProfileAdvancedSimple, MPEG4Level3b, 3041280, 352, 288, 30, 1500000), 536 new LevelLimitMPEG4( 537 MPEG4ProfileAdvancedSimple, MPEG4Level4, 3041280, 704, 576, 30, 3000000), 538 new LevelLimitMPEG4( 539 MPEG4ProfileAdvancedSimple, MPEG4Level5, 3041280, 720, 576, 30, 8000000), 540 }; 541 int size = width * height; 542 int sampleRate = size * frameRate; 543 for (LevelLimitMPEG4 levelLimitsMPEG4 : limitsMPEG4) { 544 if (((profile & (MPEG4ProfileAdvancedSimple | MPEG4ProfileSimple)) != 0) && 545 profile != levelLimitsMPEG4.profile) continue; 546 if (sampleRate <= levelLimitsMPEG4.sampleRate && width <= levelLimitsMPEG4.width && 547 height <= levelLimitsMPEG4.height && frameRate <= levelLimitsMPEG4.frameRate && 548 bitrate <= levelLimitsMPEG4.bitrate) { 549 return levelLimitsMPEG4.level; 550 } 551 } 552 // if none of the levels suffice, select the highest level 553 return MPEG4Level6; 554 } 555 getMinLevelAV1(int width, int height, int frameRate, int bitrate)556 private int getMinLevelAV1(int width, int height, int frameRate, int bitrate) { 557 class LevelLimitAV1 { 558 private LevelLimitAV1(int level, int size, int width, int height, long sampleRate, 559 int bitrate) { 560 this.level = level; 561 this.size = size; 562 this.width = width; 563 this.height = height; 564 this.sampleRate = sampleRate; 565 this.bitrate = bitrate; 566 } 567 568 private final int level; 569 private final int size; 570 private final int width; 571 private final int height; 572 private final long sampleRate; 573 private final int bitrate; 574 } 575 // taking bitrate from main profile, will also be supported by high profile 576 LevelLimitAV1[] limitsAV1 = { 577 new LevelLimitAV1(AV1Level2, 147456, 2048, 1152, 4423680, 1500000), 578 new LevelLimitAV1(AV1Level21, 278784, 2816, 1584, 8363520, 3000000), 579 new LevelLimitAV1(AV1Level3, 665856, 4352, 2448, 19975680, 6000000), 580 new LevelLimitAV1(AV1Level31, 1065024, 5504, 3096, 31950720, 10000000), 581 new LevelLimitAV1(AV1Level4, 2359296, 6144, 3456, 70778880, 12000000), 582 new LevelLimitAV1(AV1Level41, 2359296, 6144, 3456, 141557760, 20000000), 583 new LevelLimitAV1(AV1Level5, 8912896, 8192, 4352, 267386880, 30000000), 584 new LevelLimitAV1(AV1Level51, 8912896, 8192, 4352, 534773760, 40000000), 585 new LevelLimitAV1(AV1Level52, 8912896, 8192, 4352, 1069547520, 60000000), 586 new LevelLimitAV1(AV1Level53, 8912896, 8192, 4352, 1069547520, 60000000), 587 new LevelLimitAV1(AV1Level6, 35651584, 16384, 8704, 1069547520, 60000000), 588 new LevelLimitAV1(AV1Level61, 35651584, 16384, 8704, 2139095040, 100000000), 589 new LevelLimitAV1(AV1Level62, 35651584, 16384, 8704, 4278190080L, 160000000), 590 new LevelLimitAV1(AV1Level63, 35651584, 16384, 8704, 4278190080L, 160000000), 591 }; 592 int size = width * height; 593 int sampleRate = size * frameRate; 594 for (LevelLimitAV1 levelLimitsAV1 : limitsAV1) { 595 if (size <= levelLimitsAV1.size && width <= levelLimitsAV1.width && 596 height <= levelLimitsAV1.height && sampleRate <= levelLimitsAV1.sampleRate && 597 bitrate <= levelLimitsAV1.bitrate) { 598 return levelLimitsAV1.level; 599 } 600 } 601 // if none of the levels suffice or high profile, select the highest level 602 return AV1Level73; 603 } 604 getAacProfile(MediaFormat format)605 private int getAacProfile(MediaFormat format) { 606 int aacProfile = format.getInteger(MediaFormat.KEY_AAC_PROFILE, -1); 607 int profile = format.getInteger(MediaFormat.KEY_PROFILE, -1); 608 609 if (aacProfile != -1 && profile != -1) { 610 // If both aac-profile and profile are present in format, then they must be the same 611 assertTrue("aac-profile " + aacProfile + " and profile " + profile + " are different.", 612 aacProfile == profile); 613 return aacProfile; 614 } else if (aacProfile != -1) { 615 return aacProfile; 616 } else if (profile != -1) { 617 return profile; 618 } else { 619 Log.e(LOG_TAG, 620 "format doesn't contain either KEY_AAC_PROFILE or KEY_PROFILE"); 621 return -1; 622 } 623 } 624 625 @Override isFormatSimilar(MediaFormat inpFormat, MediaFormat outFormat)626 boolean isFormatSimilar(MediaFormat inpFormat, MediaFormat outFormat) { 627 if (!super.isFormatSimilar(inpFormat, outFormat)) { 628 Log.e(LOG_TAG, "Basic channel-rate/resolution comparisons failed"); 629 return false; 630 } 631 String inpMime = inpFormat.getString(MediaFormat.KEY_MIME); 632 String outMime = outFormat.getString(MediaFormat.KEY_MIME); 633 assertTrue("Input and Output mimes are different.", inpMime.equals(outMime)); 634 if (outMime.startsWith("audio/")) { 635 if (outFormat.getString(MediaFormat.KEY_MIME).equals(MediaFormat.MIMETYPE_AUDIO_AAC)) { 636 int inputProfileKey, outputProfileKey; 637 outputProfileKey = getAacProfile(outFormat); 638 inputProfileKey = getAacProfile(inpFormat); 639 if (outputProfileKey != inputProfileKey) { 640 Log.e(LOG_TAG, "aac-profile in output " + outputProfileKey + 641 " doesn't match configured input " + inputProfileKey); 642 return false; 643 } 644 } 645 } else if (outMime.startsWith("video/")) { 646 if (!outFormat.containsKey(MediaFormat.KEY_PROFILE)) { 647 Log.e(LOG_TAG, "Output format doesn't contain profile key"); 648 //TODO (b/151398466) 649 if (true) return true; 650 return false; 651 } 652 if (!outFormat.containsKey(MediaFormat.KEY_LEVEL)) { 653 Log.e(LOG_TAG, "Output format doesn't contain level key"); 654 //TODO (b/151398466) 655 if (true) return true; 656 return false; 657 } 658 if (!inpFormat.containsKey(MediaFormat.KEY_PROFILE)) { 659 Log.e(LOG_TAG, "Input format doesn't contain profile key"); 660 return false; 661 } 662 if (!inpFormat.containsKey(MediaFormat.KEY_LEVEL)) { 663 Log.e(LOG_TAG, "Input format doesn't contain level key"); 664 return false; 665 } 666 if (outFormat.getInteger(MediaFormat.KEY_PROFILE) 667 != inpFormat.getInteger(MediaFormat.KEY_PROFILE)) { 668 Log.e(LOG_TAG, "profile in output doesn't match configured input"); 669 return false; 670 } 671 if (outFormat.getInteger(MediaFormat.KEY_LEVEL) 672 != inpFormat.getInteger(MediaFormat.KEY_LEVEL)) { 673 Log.e(LOG_TAG, "level key in output doesn't match configured input"); 674 return false; 675 } 676 } else { 677 Log.w(LOG_TAG, "non media mime:" + outMime); 678 } 679 return true; 680 } 681 682 /** 683 * Sets profile and level keys in config format for encoder and validates the keys in output 684 * format if component supports the configuration and also verifies whether cdd mandated 685 * (profile, level) combination is supported 686 * Write the encoder output in all container formats that can hold the mime and validates the 687 * keys in extracted format. 688 */ 689 @Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS) testValidateProfileLevel()690 public void testValidateProfileLevel() throws IOException, InterruptedException { 691 int[] profiles = mProfileMap.get(mMime); 692 assertTrue("no profile entry found for mime" + mMime, profiles != null); 693 // cdd check initialization 694 boolean cddSupportedMime = mProfileLevelCdd.get(mMime) != null; 695 int[] profileCdd = new int[0]; 696 int levelCdd = 0; 697 if (cddSupportedMime) { 698 Pair<int[], Integer> cddProfileLevel = mProfileLevelCdd.get(mMime); 699 profileCdd = cddProfileLevel.first; 700 levelCdd = cddProfileLevel.second; 701 } 702 MediaFormat format = mConfigFormat; 703 mOutputBuff = new OutputManager(); 704 setUpSource(mInputFile); 705 mSaveToMem = true; 706 String tempMuxedFile = File.createTempFile("tmp", ".out").getAbsolutePath(); 707 { 708 mCodec = MediaCodec.createByCodecName(mCodecName); 709 MediaCodecInfo.CodecCapabilities codecCapabilities = 710 mCodec.getCodecInfo().getCapabilitiesForType(mMime); 711 for (int profile : profiles) { 712 format.setInteger(MediaFormat.KEY_PROFILE, profile); 713 // for aac encoder, alongwith setting profile, also set aac-profile as some 714 // encoders may only support one of the two keys 715 if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC)) { 716 format.setInteger(MediaFormat.KEY_AAC_PROFILE, profile); 717 } 718 int level = mIsAudio ? 0 : getMinLevel(mMime, mWidth, mHeight, 719 format.getInteger(MediaFormat.KEY_FRAME_RATE), 720 format.getInteger(MediaFormat.KEY_BIT_RATE), profile); 721 assertTrue("no min level found for mime" + mMime, level != -1); 722 if (!mIsAudio) format.setInteger(MediaFormat.KEY_LEVEL, level); 723 if (!codecCapabilities.isFormatSupported(format)) { 724 if (cddSupportedMime) { 725 boolean shallSupportProfileLevel = false; 726 if (mIsAudio) { 727 for (int cddProfile : profileCdd) { 728 if (profile == cddProfile) { 729 shallSupportProfileLevel = true; 730 } 731 } 732 } else if (profile == profileCdd[0] && level == levelCdd) { 733 shallSupportProfileLevel = true; 734 } 735 736 // TODO (b/193173880) Check if there is at least one component that 737 // supports this profile and level combination 738 if (shallSupportProfileLevel) { 739 ArrayList<MediaFormat> formats = new ArrayList<>(); 740 formats.add(format); 741 assertFalse( 742 "No components support cdd requirement profile level with \n " 743 + "format :" + format + " for mime: " + mMime, 744 selectCodecs(mMime, formats, null, false).isEmpty()); 745 } 746 Log.w(LOG_TAG, 747 "Component: " + mCodecName + " doesn't support cdd format: " + 748 format); 749 } 750 continue; 751 } 752 mOutputBuff.reset(); 753 mInfoList.clear(); 754 configureCodec(format, false, true, true); 755 mCodec.start(); 756 doWork(1); 757 queueEOS(); 758 waitForAllOutputs(); 759 MediaFormat outFormat = mCodec.getOutputFormat(); 760 /* TODO(b/147348711) */ 761 if (false) mCodec.stop(); 762 else mCodec.reset(); 763 String log = 764 String.format("format: %s \n codec: %s, mode: %s:: ", format, mCodecName, 765 "sync"); 766 assertFalse(log + " unexpected error", mAsyncHandle.hasSeenError()); 767 assertTrue(log + "configured format and output format are not similar." + 768 (ENABLE_LOGS ? "\n output format:" + outFormat : ""), 769 isFormatSimilar(format, outFormat)); 770 771 // TODO (b/151398466) 772 if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC)) { 773 Assume.assumeTrue("neither KEY_AAC_PROFILE nor KEY_PROFILE are present", 774 outFormat.containsKey(MediaFormat.KEY_AAC_PROFILE) || 775 outFormat.containsKey(MediaFormat.KEY_PROFILE)); 776 } else { 777 Assume.assumeTrue("KEY_PROFILE not present", 778 outFormat.containsKey(MediaFormat.KEY_PROFILE)); 779 } 780 Assume.assumeTrue(outFormat.containsKey(MediaFormat.KEY_LEVEL)); 781 // TODO (b/166300446) avc mime fails validation 782 if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) { 783 Log.w(LOG_TAG, "Skip validation after muxing for mime = " + mMime); 784 continue; 785 } 786 // TODO (b/166305723) hevc mime fails validation 787 if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_HEVC)) { 788 Log.w(LOG_TAG, "Skip validation after muxing for mime = " + mMime); 789 continue; 790 } 791 // TODO (b/166300448) h263 and mpeg4 mimes fails validation 792 if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_H263) || 793 mMime.equals(MediaFormat.MIMETYPE_VIDEO_MPEG4)) { 794 Log.w(LOG_TAG, "Skip validation after muxing for mime = " + mMime); 795 continue; 796 } 797 // TODO (b/184889671) aac for profile AACObjectHE fails validation 798 // TODO (b/184890155) aac for profile AACObjectLD, AACObjectELD fails validation 799 if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC) && 800 profile != AACObjectLC) { 801 Log.w(LOG_TAG, "Skip validation after muxing for mime = " + mMime + 802 " profile " + profile); 803 continue; 804 } 805 806 for (int muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_FIRST; 807 muxerFormat <= MediaMuxer.OutputFormat.MUXER_OUTPUT_LAST; muxerFormat++) { 808 if (!MuxerTest.isCodecContainerPairValid(mMime, muxerFormat)) continue; 809 ByteBuffer mBuff = mOutputBuff.getBuffer(); 810 mMuxer = new MediaMuxer(tempMuxedFile, muxerFormat); 811 try { 812 mMuxer.addTrack(outFormat); 813 mMuxer.start(); 814 for (int i = 0; i < mInfoList.size(); i++) { 815 mMuxer.writeSampleData(0, mBuff, mInfoList.get(i)); 816 } 817 mMuxer.stop(); 818 } catch (Exception e) { 819 fail(log + "error! failed write to muxer format " + muxerFormat); 820 } finally { 821 mMuxer.release(); 822 mMuxer = null; 823 } 824 MediaExtractor extractor = new MediaExtractor(); 825 extractor.setDataSource(tempMuxedFile); 826 assertEquals("Should be only 1 track ", 1, extractor.getTrackCount()); 827 MediaFormat extractedFormat = extractor.getTrackFormat(0); 828 assertTrue(log + "\nmuxer input config = " + outFormat + 829 "\ninput format and extracted format are not similar." + 830 "\nextracted format:" + extractedFormat + 831 "\ncontainer format = " + muxerFormat, 832 isFormatSimilar(format, extractedFormat)); 833 extractor.release(); 834 } 835 } 836 mCodec.release(); 837 } 838 new File(tempMuxedFile).delete(); 839 } 840 } 841