1 /* 2 * Copyright (C) 2023 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.common.cts; 18 19 import static android.media.MediaCodecInfo.CodecProfileLevel.*; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertNotEquals; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 26 import android.media.MediaCodec; 27 import android.media.MediaExtractor; 28 import android.media.MediaFormat; 29 import android.util.Log; 30 import android.util.Pair; 31 32 import java.io.IOException; 33 import java.nio.ByteBuffer; 34 import java.util.HashMap; 35 36 /** 37 * Wrapper class for testing encoders support for profile and level 38 */ 39 public class EncoderProfileLevelTestBase extends CodecEncoderTestBase { 40 private static final String LOG_TAG = EncoderProfileLevelTestBase.class.getSimpleName(); 41 private static final int[] AVC_LEVELS = 42 new int[]{AVCLevel1, AVCLevel1b, AVCLevel11, AVCLevel12, AVCLevel13, AVCLevel2, 43 AVCLevel21, AVCLevel22, AVCLevel3, AVCLevel31, AVCLevel32, AVCLevel4, 44 AVCLevel41, AVCLevel42, AVCLevel5, AVCLevel51, AVCLevel52, AVCLevel6, 45 AVCLevel61, AVCLevel62}; 46 private static final int[] MPEG2_LEVELS = 47 new int[]{MPEG2LevelLL, MPEG2LevelML, MPEG2LevelH14, MPEG2LevelHL, MPEG2LevelHP}; 48 private static final int[] MPEG4_LEVELS = 49 new int[]{MPEG4Level0, MPEG4Level0b, MPEG4Level1, MPEG4Level2, MPEG4Level3, 50 MPEG4Level3b, MPEG4Level4, MPEG4Level4a, MPEG4Level5, MPEG4Level6}; 51 private static final int[] VP9_LEVELS = 52 new int[]{VP9Level1, VP9Level11, VP9Level2, VP9Level21, VP9Level3, VP9Level31, 53 VP9Level4, VP9Level41, VP9Level5, VP9Level51, VP9Level52, VP9Level6, 54 VP9Level61, VP9Level62}; 55 private static final int[] H263_LEVELS = 56 new int[]{H263Level10, H263Level20, H263Level30, H263Level40, H263Level45, 57 H263Level50, H263Level60, H263Level70}; 58 private static final int[] AV1_LEVELS = 59 new int[]{AV1Level2, AV1Level21, AV1Level3, AV1Level31, AV1Level4, AV1Level41, 60 AV1Level5, AV1Level51, AV1Level52, AV1Level53, AV1Level6, AV1Level61, 61 AV1Level62, AV1Level63}; 62 private static final int[] HEVC_LEVELS = 63 new int[]{HEVCMainTierLevel1, HEVCHighTierLevel1, HEVCMainTierLevel2, 64 HEVCHighTierLevel2, HEVCMainTierLevel21, HEVCHighTierLevel21, 65 HEVCMainTierLevel3, HEVCHighTierLevel3, HEVCMainTierLevel31, 66 HEVCHighTierLevel31, HEVCMainTierLevel4, HEVCHighTierLevel4, 67 HEVCMainTierLevel41, HEVCHighTierLevel41, HEVCMainTierLevel5, 68 HEVCHighTierLevel5, HEVCMainTierLevel51, HEVCHighTierLevel51, 69 HEVCMainTierLevel52, HEVCHighTierLevel52, HEVCMainTierLevel6, 70 HEVCHighTierLevel6, HEVCHighTierLevel61, HEVCHighTierLevel62, 71 HEVCMainTierLevel61, HEVCMainTierLevel62}; 72 private static final int[] APV_LEVELS = 73 new int[]{APVLevel1Band0, APVLevel1Band1, APVLevel1Band2, APVLevel1Band3, 74 APVLevel11Band0, APVLevel11Band1, APVLevel11Band2, APVLevel11Band3, 75 APVLevel2Band0, APVLevel2Band1, APVLevel2Band2, APVLevel2Band3, 76 APVLevel21Band0, APVLevel21Band1, APVLevel21Band2, APVLevel21Band3, 77 APVLevel3Band0, APVLevel3Band1, APVLevel3Band2, APVLevel3Band3, 78 APVLevel31Band0, APVLevel31Band1, APVLevel31Band2, APVLevel31Band3, 79 APVLevel4Band0, APVLevel4Band1, APVLevel4Band2, APVLevel4Band3, 80 APVLevel41Band0, APVLevel41Band1, APVLevel41Band2, APVLevel41Band3, 81 APVLevel5Band0, APVLevel5Band1, APVLevel5Band2, APVLevel5Band3, 82 APVLevel51Band0, APVLevel51Band1, APVLevel51Band2, APVLevel51Band3, 83 APVLevel6Band0, APVLevel6Band1, APVLevel6Band2, APVLevel6Band3, 84 APVLevel61Band0, APVLevel61Band1, APVLevel61Band2, APVLevel61Band3, 85 APVLevel7Band0, APVLevel7Band1, APVLevel7Band2, APVLevel7Band3, 86 APVLevel71Band0, APVLevel71Band1, APVLevel71Band2, APVLevel71Band3}; 87 88 public static final HashMap<String, int[]> LEVEL_MAP = new HashMap<>(); 89 90 static { LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_AVC, AVC_LEVELS)91 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_AVC, AVC_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_MPEG2, MPEG2_LEVELS)92 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_MPEG2, MPEG2_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_MPEG4, MPEG4_LEVELS)93 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_MPEG4, MPEG4_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_VP9, VP9_LEVELS)94 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_VP9, VP9_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_H263, H263_LEVELS)95 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_H263, H263_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_HEVC, HEVC_LEVELS)96 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_HEVC, HEVC_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_AV1, AV1_LEVELS)97 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_AV1, AV1_LEVELS); LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_APV, APV_LEVELS)98 LEVEL_MAP.put(MediaFormat.MIMETYPE_VIDEO_APV, APV_LEVELS); 99 } 100 divUp(int num, int den)101 private static int divUp(int num, int den) { 102 return (num + den - 1) / den; 103 } 104 getMinLevel(String mediaType, int width, int height, int frameRate, int bitrate, int profile)105 public static int getMinLevel(String mediaType, int width, int height, int frameRate, 106 int bitrate, int profile) { 107 switch (mediaType) { 108 case MediaFormat.MIMETYPE_VIDEO_AVC: 109 return getMinLevelAVC(width, height, frameRate, bitrate); 110 case MediaFormat.MIMETYPE_VIDEO_HEVC: 111 return getMinLevelHEVC(width, height, frameRate, bitrate); 112 case MediaFormat.MIMETYPE_VIDEO_H263: 113 return getMinLevelH263(width, height, frameRate, bitrate); 114 case MediaFormat.MIMETYPE_VIDEO_MPEG2: 115 return getMinLevelMPEG2(width, height, frameRate, bitrate); 116 case MediaFormat.MIMETYPE_VIDEO_MPEG4: 117 return getMinLevelMPEG4(width, height, frameRate, bitrate, profile); 118 case MediaFormat.MIMETYPE_VIDEO_VP9: 119 return getMinLevelVP9(width, height, frameRate, bitrate); 120 case MediaFormat.MIMETYPE_VIDEO_AV1: 121 return getMinLevelAV1(width, height, frameRate, bitrate); 122 case MediaFormat.MIMETYPE_VIDEO_APV: 123 return getMinLevelAPV(width, height, frameRate, bitrate); 124 default: 125 return -1; 126 } 127 } 128 getMinLevelAVC(int width, int height, int frameRate, int bitrate)129 private static int getMinLevelAVC(int width, int height, int frameRate, int bitrate) { 130 class LevelLimitAVC { 131 private LevelLimitAVC(int level, int mbsPerSec, long mbs, int bitrate) { 132 this.mLevel = level; 133 this.mMbsPerSec = mbsPerSec; 134 this.mMbs = mbs; 135 this.mBitrate = bitrate; 136 } 137 138 private final int mLevel; 139 private final int mMbsPerSec; 140 private final long mMbs; 141 private final int mBitrate; 142 } 143 LevelLimitAVC[] limitsAVC = { 144 new LevelLimitAVC(AVCLevel1, 1485, 99, 64000), 145 new LevelLimitAVC(AVCLevel1b, 1485, 99, 128000), 146 new LevelLimitAVC(AVCLevel11, 3000, 396, 192000), 147 new LevelLimitAVC(AVCLevel12, 6000, 396, 384000), 148 new LevelLimitAVC(AVCLevel13, 11880, 396, 768000), 149 new LevelLimitAVC(AVCLevel2, 11880, 396, 2000000), 150 new LevelLimitAVC(AVCLevel21, 19800, 792, 4000000), 151 new LevelLimitAVC(AVCLevel22, 20250, 1620, 4000000), 152 new LevelLimitAVC(AVCLevel3, 40500, 1620, 10000000), 153 new LevelLimitAVC(AVCLevel31, 108000, 3600, 14000000), 154 new LevelLimitAVC(AVCLevel32, 216000, 5120, 20000000), 155 new LevelLimitAVC(AVCLevel4, 245760, 8192, 20000000), 156 new LevelLimitAVC(AVCLevel41, 245760, 8192, 50000000), 157 new LevelLimitAVC(AVCLevel42, 522240, 8704, 50000000), 158 new LevelLimitAVC(AVCLevel5, 589824, 22080, 135000000), 159 new LevelLimitAVC(AVCLevel51, 983040, 36864, 240000000), 160 new LevelLimitAVC(AVCLevel52, 2073600, 36864, 240000000), 161 new LevelLimitAVC(AVCLevel6, 4177920, 139264, 240000000), 162 new LevelLimitAVC(AVCLevel61, 8355840, 139264, 480000000), 163 new LevelLimitAVC(AVCLevel62, 16711680, 139264, 800000000), 164 }; 165 int blockSize = 16; 166 int mbs = divUp(width, blockSize) * divUp(height, blockSize); 167 float mbsPerSec = mbs * frameRate; 168 for (LevelLimitAVC levelLimitsAVC : limitsAVC) { 169 if (mbs <= levelLimitsAVC.mMbs && mbsPerSec <= levelLimitsAVC.mMbsPerSec 170 && bitrate <= levelLimitsAVC.mBitrate) { 171 return levelLimitsAVC.mLevel; 172 } 173 } 174 // if none of the levels suffice, select the highest level 175 return AVCLevel62; 176 } 177 getMinLevelHEVC(int width, int height, int frameRate, int bitrate)178 private static int getMinLevelHEVC(int width, int height, int frameRate, int bitrate) { 179 class LevelLimitHEVC { 180 private LevelLimitHEVC(int level, long pixelsPerSec, long pixelsPerFrame, int bitrate) { 181 this.mLevel = level; 182 this.mPixelsPerSec = pixelsPerSec; 183 this.mPixelsPerFrame = pixelsPerFrame; 184 this.mBitrate = bitrate; 185 } 186 187 private final int mLevel; 188 private final long mPixelsPerSec; 189 private final long mPixelsPerFrame; 190 private final int mBitrate; 191 } 192 LevelLimitHEVC[] limitsHEVC = { 193 new LevelLimitHEVC(HEVCMainTierLevel1, 552960, 36864, 128000), 194 new LevelLimitHEVC(HEVCMainTierLevel2, 3686400, 122880, 1500000), 195 new LevelLimitHEVC(HEVCMainTierLevel21, 7372800, 245760, 3000000), 196 new LevelLimitHEVC(HEVCMainTierLevel3, 16588800, 552960, 6000000), 197 new LevelLimitHEVC(HEVCMainTierLevel31, 33177600, 983040, 10000000), 198 new LevelLimitHEVC(HEVCMainTierLevel4, 66846720, 2228224, 12000000), 199 new LevelLimitHEVC(HEVCHighTierLevel4, 66846720, 2228224, 30000000), 200 new LevelLimitHEVC(HEVCMainTierLevel41, 133693440, 2228224, 20000000), 201 new LevelLimitHEVC(HEVCHighTierLevel41, 133693440, 2228224, 50000000), 202 new LevelLimitHEVC(HEVCMainTierLevel5, 267386880, 8912896, 25000000), 203 new LevelLimitHEVC(HEVCHighTierLevel5, 267386880, 8912896, 100000000), 204 new LevelLimitHEVC(HEVCMainTierLevel51, 534773760, 8912896, 40000000), 205 new LevelLimitHEVC(HEVCHighTierLevel51, 534773760, 8912896, 160000000), 206 new LevelLimitHEVC(HEVCMainTierLevel52, 1069547520, 8912896, 60000000), 207 new LevelLimitHEVC(HEVCHighTierLevel52, 1069547520, 8912896, 240000000), 208 new LevelLimitHEVC(HEVCMainTierLevel6, 1069547520, 35651584, 60000000), 209 new LevelLimitHEVC(HEVCHighTierLevel6, 1069547520, 35651584, 240000000), 210 new LevelLimitHEVC(HEVCMainTierLevel61, 2139095040, 35651584, 120000000), 211 new LevelLimitHEVC(HEVCHighTierLevel61, 2139095040, 35651584, 480000000), 212 new LevelLimitHEVC(HEVCMainTierLevel62, 4278190080L, 35651584, 240000000), 213 new LevelLimitHEVC(HEVCHighTierLevel62, 4278190080L, 35651584, 800000000), 214 }; 215 int blockSize = 8; 216 int blocks = divUp(width, blockSize) * divUp(height, blockSize); 217 long pixelsPerFrame = blocks * blockSize * blockSize; 218 long pixelsPerSec = pixelsPerFrame * frameRate; 219 for (LevelLimitHEVC levelLimitsHEVC : limitsHEVC) { 220 if (pixelsPerFrame <= levelLimitsHEVC.mPixelsPerFrame 221 && pixelsPerSec <= levelLimitsHEVC.mPixelsPerSec 222 && bitrate <= levelLimitsHEVC.mBitrate) { 223 return levelLimitsHEVC.mLevel; 224 } 225 } 226 // if none of the levels suffice, select the highest level 227 return HEVCHighTierLevel62; 228 } 229 getMinLevelH263(int width, int height, int frameRate, int bitrate)230 private static int getMinLevelH263(int width, int height, int frameRate, int bitrate) { 231 class LevelLimitH263 { 232 private LevelLimitH263(int level, long pixelsPerSec, int width, int height, 233 int frameRate, int bitrate) { 234 this.mLevel = level; 235 this.mPixelsPerSec = pixelsPerSec; 236 this.mWidth = width; 237 this.mHeight = height; 238 this.mFrameRate = frameRate; 239 this.mBitrate = bitrate; 240 } 241 242 private final int mLevel; 243 private final long mPixelsPerSec; 244 private final int mWidth; 245 private final int mHeight; 246 private final int mFrameRate; 247 private final int mBitrate; 248 } 249 LevelLimitH263[] limitsH263 = { 250 new LevelLimitH263(H263Level10, 380160, 176, 144, 15, 64000), 251 new LevelLimitH263(H263Level45, 380160, 176, 144, 15, 128000), 252 new LevelLimitH263(H263Level20, 1520640, 352, 288, 30, 128000), 253 new LevelLimitH263(H263Level30, 3041280, 352, 288, 30, 384000), 254 new LevelLimitH263(H263Level40, 3041280, 352, 288, 30, 2048000), 255 new LevelLimitH263(H263Level50, 5068800, 352, 288, 60, 4096000), 256 new LevelLimitH263(H263Level60, 10368000, 720, 288, 60, 8192000), 257 new LevelLimitH263(H263Level70, 20736000, 720, 576, 60, 16384000), 258 }; 259 int blockSize = 16; 260 int mbs = divUp(width, blockSize) * divUp(height, blockSize); 261 int size = mbs * blockSize * blockSize; 262 int pixelsPerSec = size * frameRate; 263 for (LevelLimitH263 levelLimitsH263 : limitsH263) { 264 if (pixelsPerSec <= levelLimitsH263.mPixelsPerSec && height <= levelLimitsH263.mHeight 265 && width <= levelLimitsH263.mWidth && frameRate <= levelLimitsH263.mFrameRate 266 && bitrate <= levelLimitsH263.mBitrate) { 267 return levelLimitsH263.mLevel; 268 } 269 } 270 // if none of the levels suffice, select the highest level 271 return H263Level70; 272 } 273 getMinLevelVP9(int width, int height, int frameRate, int bitrate)274 private static int getMinLevelVP9(int width, int height, int frameRate, int bitrate) { 275 class LevelLimitVP9 { 276 private LevelLimitVP9(int level, long pixelsPerSec, int size, int maxWH, int bitrate) { 277 this.mLevel = level; 278 this.mPixelsPerSec = pixelsPerSec; 279 this.mSize = size; 280 this.mMaxWH = maxWH; 281 this.mBitrate = bitrate; 282 } 283 284 private final int mLevel; 285 private final long mPixelsPerSec; 286 private final int mSize; 287 private final int mMaxWH; 288 private final int mBitrate; 289 } 290 LevelLimitVP9[] limitsVP9 = { 291 new LevelLimitVP9(VP9Level1, 829440, 36864, 512, 200000), 292 new LevelLimitVP9(VP9Level11, 2764800, 73728, 768, 800000), 293 new LevelLimitVP9(VP9Level2, 4608000, 122880, 960, 1800000), 294 new LevelLimitVP9(VP9Level21, 9216000, 245760, 1344, 3600000), 295 new LevelLimitVP9(VP9Level3, 20736000, 552960, 2048, 7200000), 296 new LevelLimitVP9(VP9Level31, 36864000, 983040, 2752, 12000000), 297 new LevelLimitVP9(VP9Level4, 83558400, 2228224, 4160, 18000000), 298 new LevelLimitVP9(VP9Level41, 160432128, 2228224, 4160, 30000000), 299 new LevelLimitVP9(VP9Level5, 311951360, 8912896, 8384, 60000000), 300 new LevelLimitVP9(VP9Level51, 588251136, 8912896, 8384, 120000000), 301 new LevelLimitVP9(VP9Level52, 1176502272, 8912896, 8384, 180000000), 302 new LevelLimitVP9(VP9Level6, 1176502272, 35651584, 16832, 180000000), 303 new LevelLimitVP9(VP9Level61, 2353004544L, 35651584, 16832, 240000000), 304 new LevelLimitVP9(VP9Level62, 4706009088L, 35651584, 16832, 480000000), 305 }; 306 int size = width * height; 307 int pixelsPerSec = size * frameRate; 308 int maxWH = Math.max(width, height); 309 for (LevelLimitVP9 levelLimitsVP9 : limitsVP9) { 310 if (pixelsPerSec <= levelLimitsVP9.mPixelsPerSec && size <= levelLimitsVP9.mSize 311 && maxWH <= levelLimitsVP9.mMaxWH && bitrate <= levelLimitsVP9.mBitrate) { 312 return levelLimitsVP9.mLevel; 313 } 314 } 315 // if none of the levels suffice, select the highest level 316 return VP9Level62; 317 } 318 getMinLevelMPEG2(int width, int height, int frameRate, int bitrate)319 private static int getMinLevelMPEG2(int width, int height, int frameRate, int bitrate) { 320 class LevelLimitMPEG2 { 321 private LevelLimitMPEG2(int level, long pixelsPerSec, int width, int height, 322 int frameRate, int bitrate) { 323 this.mLevel = level; 324 this.mPixelsPerSec = pixelsPerSec; 325 this.mWidth = width; 326 this.mHeight = height; 327 this.mFrameRate = frameRate; 328 this.mBitrate = bitrate; 329 } 330 331 private final int mLevel; 332 private final long mPixelsPerSec; 333 private final int mWidth; 334 private final int mHeight; 335 private final int mFrameRate; 336 private final int mBitrate; 337 } 338 // main profile limits, higher profiles will also support selected level 339 LevelLimitMPEG2[] limitsMPEG2 = { 340 new LevelLimitMPEG2(MPEG2LevelLL, 3041280, 352, 288, 30, 4000000), 341 new LevelLimitMPEG2(MPEG2LevelML, 10368000, 720, 576, 30, 15000000), 342 new LevelLimitMPEG2(MPEG2LevelH14, 47001600, 1440, 1088, 60, 60000000), 343 new LevelLimitMPEG2(MPEG2LevelHL, 62668800, 1920, 1088, 60, 80000000), 344 new LevelLimitMPEG2(MPEG2LevelHP, 125337600, 1920, 1088, 60, 80000000), 345 }; 346 int blockSize = 16; 347 int mbs = divUp(width, blockSize) * divUp(height, blockSize); 348 int size = mbs * blockSize * blockSize; 349 int pixelsPerSec = size * frameRate; 350 for (LevelLimitMPEG2 levelLimitsMPEG2 : limitsMPEG2) { 351 if (pixelsPerSec <= levelLimitsMPEG2.mPixelsPerSec && width <= levelLimitsMPEG2.mWidth 352 && height <= levelLimitsMPEG2.mHeight 353 && frameRate <= levelLimitsMPEG2.mFrameRate 354 && bitrate <= levelLimitsMPEG2.mBitrate) { 355 return levelLimitsMPEG2.mLevel; 356 } 357 } 358 // if none of the levels suffice, select the highest level 359 return MPEG2LevelHP; 360 } 361 getMinLevelMPEG4(int width, int height, int frameRate, int bitrate, int profile)362 private static int getMinLevelMPEG4(int width, int height, int frameRate, int bitrate, 363 int profile) { 364 class LevelLimitMPEG4 { 365 private LevelLimitMPEG4(int profile, int level, long pixelsPerSec, int width, 366 int height, int frameRate, int bitrate) { 367 this.mProfile = profile; 368 this.mLevel = level; 369 this.mPixelsPerSec = pixelsPerSec; 370 this.mWidth = width; 371 this.mHeight = height; 372 this.mFrameRate = frameRate; 373 this.mBitrate = bitrate; 374 } 375 376 private final int mProfile; 377 private final int mLevel; 378 private final long mPixelsPerSec; 379 private final int mWidth; 380 private final int mHeight; 381 private final int mFrameRate; 382 private final int mBitrate; 383 } 384 // simple profile limits, higher profiles will also support selected level 385 LevelLimitMPEG4[] limitsMPEG4 = { 386 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0, 380160, 176, 144, 15, 64000), 387 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level1, 380160, 176, 144, 30, 64000), 388 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0b, 380160, 176, 144, 15, 128000), 389 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level2, 1520640, 352, 288, 30, 128000), 390 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level3, 3041280, 352, 288, 30, 384000), 391 new LevelLimitMPEG4( 392 MPEG4ProfileSimple, MPEG4Level4a, 9216000, 640, 480, 30, 4000000), 393 new LevelLimitMPEG4( 394 MPEG4ProfileSimple, MPEG4Level5, 10368000, 720, 576, 30, 8000000), 395 new LevelLimitMPEG4( 396 MPEG4ProfileSimple, MPEG4Level6, 27648000, 1280, 720, 30, 12000000), 397 new LevelLimitMPEG4( 398 MPEG4ProfileAdvancedSimple, MPEG4Level1, 760320, 176, 144, 30, 128000), 399 new LevelLimitMPEG4( 400 MPEG4ProfileAdvancedSimple, MPEG4Level2, 1520640, 352, 288, 30, 384000), 401 new LevelLimitMPEG4( 402 MPEG4ProfileAdvancedSimple, MPEG4Level3, 3041280, 352, 288, 30, 768000), 403 new LevelLimitMPEG4( 404 MPEG4ProfileAdvancedSimple, MPEG4Level3b, 3041280, 352, 288, 30, 1500000), 405 new LevelLimitMPEG4( 406 MPEG4ProfileAdvancedSimple, MPEG4Level4, 6082560, 704, 576, 30, 3000000), 407 new LevelLimitMPEG4( 408 MPEG4ProfileAdvancedSimple, MPEG4Level5, 12441600, 720, 576, 30, 8000000), 409 }; 410 int blockSize = 16; 411 int mbs = divUp(width, blockSize) * divUp(height, blockSize); 412 int size = mbs * blockSize * blockSize; 413 int pixelsPerSec = size * frameRate; 414 if (profile != MPEG4ProfileAdvancedSimple && profile != MPEG4ProfileSimple) { 415 throw new RuntimeException("Unrecognized profile " + profile + " for " 416 + MediaFormat.MIMETYPE_VIDEO_MPEG4); 417 } 418 for (LevelLimitMPEG4 levelLimitsMPEG4 : limitsMPEG4) { 419 if (profile == levelLimitsMPEG4.mProfile 420 && pixelsPerSec <= levelLimitsMPEG4.mPixelsPerSec 421 && width <= levelLimitsMPEG4.mWidth && height <= levelLimitsMPEG4.mHeight 422 && frameRate <= levelLimitsMPEG4.mFrameRate 423 && bitrate <= levelLimitsMPEG4.mBitrate) { 424 return levelLimitsMPEG4.mLevel; 425 } 426 } 427 // if none of the levels suffice, select the highest level 428 return MPEG4Level6; 429 } 430 getMinLevelAV1(int width, int height, int frameRate, int bitrate)431 private static int getMinLevelAV1(int width, int height, int frameRate, int bitrate) { 432 class LevelLimitAV1 { 433 private LevelLimitAV1(int level, int size, int width, int height, long pixelsPerSec, 434 int bitrate) { 435 this.mLevel = level; 436 this.mSize = size; 437 this.mWidth = width; 438 this.mHeight = height; 439 this.mPixelsPerSec = pixelsPerSec; 440 this.mBitrate = bitrate; 441 } 442 443 private final int mLevel; 444 private final int mSize; 445 private final int mWidth; 446 private final int mHeight; 447 private final long mPixelsPerSec; 448 private final int mBitrate; 449 } 450 // taking bitrate from main profile, will also be supported by high profile 451 LevelLimitAV1[] limitsAV1 = { 452 new LevelLimitAV1(AV1Level2, 147456, 2048, 1152, 4423680, 1500000), 453 new LevelLimitAV1(AV1Level21, 278784, 2816, 1584, 8363520, 3000000), 454 new LevelLimitAV1(AV1Level3, 665856, 4352, 2448, 19975680, 6000000), 455 new LevelLimitAV1(AV1Level31, 1065024, 5504, 3096, 31950720, 10000000), 456 new LevelLimitAV1(AV1Level4, 2359296, 6144, 3456, 70778880, 30000000), 457 new LevelLimitAV1(AV1Level41, 2359296, 6144, 3456, 141557760, 50000000), 458 new LevelLimitAV1(AV1Level5, 8912896, 8192, 4352, 267386880, 100000000), 459 new LevelLimitAV1(AV1Level51, 8912896, 8192, 4352, 534773760, 160000000), 460 new LevelLimitAV1(AV1Level52, 8912896, 8192, 4352, 1069547520, 240000000), 461 new LevelLimitAV1(AV1Level53, 8912896, 8192, 4352, 1069547520, 240000000), 462 new LevelLimitAV1(AV1Level6, 35651584, 16384, 8704, 1069547520, 240000000), 463 new LevelLimitAV1(AV1Level61, 35651584, 16384, 8704, 2139095040, 480000000), 464 new LevelLimitAV1(AV1Level62, 35651584, 16384, 8704, 4278190080L, 800000000), 465 new LevelLimitAV1(AV1Level63, 35651584, 16384, 8704, 4278190080L, 800000000), 466 }; 467 int size = width * height; 468 long pixelsPerSec = (long) size * frameRate; 469 for (LevelLimitAV1 levelLimitsAV1 : limitsAV1) { 470 if (size <= levelLimitsAV1.mSize && width <= levelLimitsAV1.mWidth 471 && height <= levelLimitsAV1.mHeight 472 && pixelsPerSec <= levelLimitsAV1.mPixelsPerSec 473 && bitrate <= levelLimitsAV1.mBitrate) { 474 return levelLimitsAV1.mLevel; 475 } 476 } 477 // if none of the levels suffice or high profile, select the highest level 478 return AV1Level63; 479 } 480 getMinLevelAPV(int width, int height, int frameRate, int bitrate)481 private static int getMinLevelAPV(int width, int height, int frameRate, int bitrate) { 482 class LevelLimitAPV { 483 private LevelLimitAPV(int level, long samplesPerSec, int bitrateKbps) { 484 this.mLevel = level; 485 this.mSamplesPerSec = samplesPerSec; 486 this.mBitrateKbps = bitrateKbps; 487 } 488 489 private final int mLevel; 490 private final long mSamplesPerSec; 491 private final int mBitrateKbps; 492 } 493 LevelLimitAPV[] limitsAPV = { 494 new LevelLimitAPV(APVLevel1Band0, 3041280L, 7000), 495 new LevelLimitAPV(APVLevel1Band1, 3041280L, 11000), 496 new LevelLimitAPV(APVLevel1Band2, 3041280L, 14000), 497 new LevelLimitAPV(APVLevel1Band3, 3041280L, 21000), 498 new LevelLimitAPV(APVLevel11Band0, 6082560L, 14000), 499 new LevelLimitAPV(APVLevel11Band1, 6082560L, 21000), 500 new LevelLimitAPV(APVLevel11Band2, 6082560L, 28000), 501 new LevelLimitAPV(APVLevel11Band3, 6082560L, 42000), 502 new LevelLimitAPV(APVLevel2Band0, 15667200L, 36000), 503 new LevelLimitAPV(APVLevel2Band1, 15667200L, 53000), 504 new LevelLimitAPV(APVLevel2Band2, 15667200L, 71000), 505 new LevelLimitAPV(APVLevel2Band3, 15667200L, 106000), 506 new LevelLimitAPV(APVLevel21Band0, 31334400L, 71000), 507 new LevelLimitAPV(APVLevel21Band1, 31334400L, 106000), 508 new LevelLimitAPV(APVLevel21Band2, 31334400L, 141000), 509 new LevelLimitAPV(APVLevel21Band3, 31334400L, 212000), 510 new LevelLimitAPV(APVLevel3Band0, 66846720L, 101000), 511 new LevelLimitAPV(APVLevel3Band1, 66846720L, 151000), 512 new LevelLimitAPV(APVLevel3Band2, 66846720L, 201000), 513 new LevelLimitAPV(APVLevel3Band3, 66846720L, 301000), 514 new LevelLimitAPV(APVLevel31Band0, 133693440L, 201000), 515 new LevelLimitAPV(APVLevel31Band1, 133693440L, 301000), 516 new LevelLimitAPV(APVLevel31Band2, 133693440L, 401000), 517 new LevelLimitAPV(APVLevel31Band3, 133693440L, 602000), 518 new LevelLimitAPV(APVLevel4Band0, 265420800L, 401000), 519 new LevelLimitAPV(APVLevel4Band1, 265420800L, 602000), 520 new LevelLimitAPV(APVLevel4Band2, 265420800L, 780000), 521 new LevelLimitAPV(APVLevel4Band3, 265420800L, 1170000), 522 new LevelLimitAPV(APVLevel41Band0, 530841600L, 780000), 523 new LevelLimitAPV(APVLevel41Band1, 530841600L, 1170000), 524 new LevelLimitAPV(APVLevel41Band2, 530841600L, 1560000), 525 new LevelLimitAPV(APVLevel41Band3, 530841600L, 2340000), 526 new LevelLimitAPV(APVLevel5Band0, 1061683200L, 1560000), 527 new LevelLimitAPV(APVLevel5Band1, 1061683200L, 2340000), 528 new LevelLimitAPV(APVLevel5Band2, 1061683200L, 3324000), 529 new LevelLimitAPV(APVLevel5Band3, 1061683200L, 4986000), 530 new LevelLimitAPV(APVLevel51Band0, 2123366400L, 3324000), 531 new LevelLimitAPV(APVLevel51Band1, 2123366400L, 4986000), 532 new LevelLimitAPV(APVLevel51Band2, 2123366400L, 6648000), 533 new LevelLimitAPV(APVLevel51Band3, 2123366400L, 9972000), 534 new LevelLimitAPV(APVLevel6Band0, 4777574400L, 6648000), 535 new LevelLimitAPV(APVLevel6Band1, 4777574400L, 9972000), 536 new LevelLimitAPV(APVLevel6Band2, 4777574400L, 13296000), 537 new LevelLimitAPV(APVLevel6Band3, 4777574400L, 19944000), 538 new LevelLimitAPV(APVLevel61Band0, 8493465600L, 13296000), 539 new LevelLimitAPV(APVLevel61Band1, 8493465600L, 19944000), 540 new LevelLimitAPV(APVLevel61Band2, 8493465600L, 26592000), 541 new LevelLimitAPV(APVLevel61Band3, 8493465600L, 39888000), 542 new LevelLimitAPV(APVLevel7Band0, 16986931200L, 26592000), 543 new LevelLimitAPV(APVLevel7Band1, 16986931200L, 39888000), 544 new LevelLimitAPV(APVLevel7Band2, 16986931200L, 53184000), 545 new LevelLimitAPV(APVLevel7Band3, 16986931200L, 79776000), 546 new LevelLimitAPV(APVLevel71Band0, 33973862400L, 53184000), 547 new LevelLimitAPV(APVLevel71Band1, 33973862400L, 79776000), 548 new LevelLimitAPV(APVLevel71Band2, 33973862400L, 106368000), 549 new LevelLimitAPV(APVLevel71Band3, 33973862400L, 159552000), 550 }; 551 long samplesPerSec = (long) width * height * frameRate; 552 for (LevelLimitAPV levelLimitsAPV : limitsAPV) { 553 if (samplesPerSec <= levelLimitsAPV.mSamplesPerSec 554 && bitrate <= levelLimitsAPV.mBitrateKbps * 1000) { 555 return levelLimitsAPV.mLevel; 556 } 557 } 558 // if none of the levels suffice, select the highest level 559 return APVLevel71Band3; 560 } 561 562 protected BitStreamUtils.ParserBase mParser; 563 protected Pair<Integer, Integer> mProfileLevel; 564 protected boolean mGotCsd; 565 EncoderProfileLevelTestBase(String encoder, String mediaType, EncoderConfigParams[] encCfgParams, String allTestParams)566 public EncoderProfileLevelTestBase(String encoder, String mediaType, 567 EncoderConfigParams[] encCfgParams, String allTestParams) { 568 super(encoder, mediaType, encCfgParams, allTestParams); 569 } 570 571 @Override resetContext(boolean isAsync, boolean signalEOSWithLastFrame)572 protected void resetContext(boolean isAsync, boolean signalEOSWithLastFrame) { 573 super.resetContext(isAsync, signalEOSWithLastFrame); 574 mParser = BitStreamUtils.getParserObject(mMediaType); 575 mProfileLevel = null; 576 mGotCsd = false; 577 } 578 579 @Override dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info)580 protected void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) { 581 if (info.size > 0 && mProfileLevel == null) { 582 if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { 583 ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex); 584 mProfileLevel = BitStreamUtils.getProfileLevelFromBitStream(buf, info, mParser); 585 mGotCsd = true; 586 } else { 587 if ((mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_VP9) || mMediaType.equals( 588 MediaFormat.MIMETYPE_VIDEO_H263)) && mOutputCount == 0) { 589 ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex); 590 mProfileLevel = BitStreamUtils.getProfileLevelFromBitStream(buf, info, mParser); 591 } 592 } 593 } 594 super.dequeueOutput(bufferIndex, info); 595 } 596 getProfile(MediaFormat format, String msg)597 private int getProfile(MediaFormat format, String msg) { 598 // Query output profile. KEY_PROFILE gets precedence over KEY_AAC_PROFILE 599 int aacProfile = format.getInteger(MediaFormat.KEY_AAC_PROFILE, -1); 600 int profile = format.getInteger(MediaFormat.KEY_PROFILE, aacProfile); 601 if (profile != -1) { 602 return profile; 603 } else { 604 fail(msg + "profile key not present in format " + format + mTestConfig + mTestEnv); 605 } 606 return -1; 607 } 608 getLevel(MediaFormat format, String msg)609 private int getLevel(MediaFormat format, String msg) { 610 assertTrue(msg + "level not present in format " + format + mTestConfig + mTestEnv, 611 format.containsKey(MediaFormat.KEY_LEVEL)); 612 return format.getInteger(MediaFormat.KEY_LEVEL); 613 } 614 validateProfile(int exp, int got, String msg)615 protected void validateProfile(int exp, int got, String msg) { 616 if (mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) { 617 if (exp == AVCProfileBaseline || exp == AVCProfileConstrainedBaseline) { 618 assertTrue(String.format(msg + "Profile information mismatch, Expected %d, Got %d ", 619 exp, got) + mTestConfig + mTestEnv, 620 (got == AVCProfileBaseline || got == AVCProfileConstrainedBaseline)); 621 return; 622 } else if (exp == AVCProfileHigh || exp == AVCProfileConstrainedHigh) { 623 assertTrue(String.format(msg + "Profile information mismatch, Expected %d, Got %d ", 624 exp, got) + mTestConfig + mTestEnv, 625 (got == AVCProfileHigh || got == AVCProfileConstrainedHigh)); 626 return; 627 } 628 } 629 assertEquals(String.format(msg + "Profile information mismatch, Expected %d, Got %d ", 630 exp, got) + mTestConfig + mTestEnv, exp, got); 631 } 632 validateLevel(int exp, int got, String msg)633 protected void validateLevel(int exp, int got, String msg) { 634 assertEquals(String.format(msg + "Level information mismatch, Expected %d, Got %d ", 635 exp, got) + mTestConfig + mTestEnv, exp, got); 636 } 637 validateMinLevel(int min, int got, String msg)638 protected void validateMinLevel(int min, int got, String msg) { 639 String log = String.format(msg + "Level information unexpected, Expected at least %d," 640 + " Got %d ", min, got) + mTestConfig + mTestEnv; 641 // H263 level 45 is out of order. 642 if (mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_H263) && min == H263Level45) { 643 // If we are expecting a min level45, then any level other than the ones below 644 // level45 (level10) should be ok 645 assertNotEquals(log, H263Level10, got); 646 } else if (mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_H263) && got == H263Level45) { 647 // If we got level45, then min level must be level10 or level45 648 assertEquals(log, H263Level10, min); 649 } else if (mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_MPEG4) 650 && mActiveEncCfg.mProfile == MPEG4ProfileAdvancedSimple && min == MPEG4Level1) { 651 // In mpeg4, for advanced simple profile, level0 and level1 have same limits 652 assertTrue(log, got == MPEG4Level0 || min <= got); 653 } else { 654 assertTrue(log, min <= got); 655 } 656 } 657 validateBitStreamForProfileAndLevel(int cfgProfile, int cfgLevel)658 protected void validateBitStreamForProfileAndLevel(int cfgProfile, int cfgLevel) { 659 if (mProfileLevel != null) { 660 validateProfile(cfgProfile, mProfileLevel.first, "Validating profile of bitstream : "); 661 if (mProfileLevel.second != -1) { 662 validateMinLevel(cfgLevel, mProfileLevel.second, 663 "Validating level of bitstream : "); 664 } 665 } 666 } 667 validateFormatForProfileAndLevelWRTBitstream(MediaFormat format, String msg)668 protected void validateFormatForProfileAndLevelWRTBitstream(MediaFormat format, String msg) { 669 if (mProfileLevel != null) { 670 validateProfile(mProfileLevel.first, getProfile(format, msg), msg); 671 if (mProfileLevel.second != -1) { 672 validateLevel(mProfileLevel.second, getLevel(format, msg), msg); 673 } 674 } 675 } 676 validateFormatForProfileAndLevelWRTCfg(MediaFormat format, String msg)677 protected void validateFormatForProfileAndLevelWRTCfg(MediaFormat format, String msg) { 678 validateProfile(mActiveEncCfg.mProfile, getProfile(format, msg), msg); 679 // Few bitstream specifications (e.g. vp9, h263) do not have a place holder for level. 680 // By extension, it is acceptable if this information is not provided in csd. 681 // But, if present, it MUST be according to the test requirements. 682 if (mActiveEncCfg.mLevel != -1 683 && (format.containsKey(MediaFormat.KEY_LEVEL) 684 || (!mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_VP9) 685 && !mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_H263)))) { 686 validateMinLevel(mActiveEncCfg.mLevel, getLevel(format, msg), msg); 687 } 688 } 689 validateFormatForProfileAndLevel(MediaFormat format, String msg)690 protected void validateFormatForProfileAndLevel(MediaFormat format, String msg) { 691 validateFormatForProfileAndLevelWRTBitstream(format, msg + " wrt to bitstream : "); 692 validateFormatForProfileAndLevelWRTCfg(format, msg + " wrt to cfg : "); 693 } 694 validateProfileAndLevel()695 protected MediaFormat validateProfileAndLevel() throws IOException { 696 // check if bitstream is in accordance with configured profile and level info. 697 if (mProfileLevel != null) { 698 validateBitStreamForProfileAndLevel(mActiveEncCfg.mProfile, mActiveEncCfg.mLevel); 699 } 700 701 // check if output format is in accordance with configured profile and level info. 702 if (mCodecName.toUpperCase().startsWith("OMX")) { 703 Log.i(LOG_TAG, "omx components don't present prof/level in outputformat"); 704 } else { 705 validateFormatForProfileAndLevel(mOutFormat, "Testing output format : "); 706 } 707 708 // check if extracted output profile and level information are in accordance with 709 // configured profile and level info 710 if (mMuxOutput && !mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_H263)) { 711 // Explicit signaling of header information such as profile, level etc is not 712 // directly available as HLS in H263 header. That information is conveyed through 713 // external means of RTP header 714 MediaExtractor extractor = new MediaExtractor(); 715 extractor.setDataSource(mMuxedOutputFile); 716 assertEquals("Should be only 1 track \n" + mTestConfig + mTestEnv, 1, 717 extractor.getTrackCount()); 718 MediaFormat trackFormat = extractor.getTrackFormat(0); 719 extractor.release(); 720 if (mGotCsd || (trackFormat.containsKey(MediaFormat.KEY_PROFILE) 721 || trackFormat.containsKey(MediaFormat.KEY_LEVEL))) { 722 validateFormatForProfileAndLevel(trackFormat, "Testing extractor format :- "); 723 } 724 return trackFormat; 725 } 726 return null; 727 } 728 } 729