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