1 /* 2 * Copyright 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.media.mediaediting.cts; 18 19 import static androidx.media3.common.MimeTypes.VIDEO_H264; 20 import static androidx.media3.common.MimeTypes.VIDEO_H265; 21 import static androidx.media3.common.util.Assertions.checkState; 22 import static androidx.media3.common.util.Assertions.checkStateNotNull; 23 24 import android.media.MediaExtractor; 25 import android.media.MediaFormat; 26 27 import androidx.annotation.Nullable; 28 import androidx.media3.common.C; 29 import androidx.media3.common.ColorInfo; 30 import androidx.media3.common.Format; 31 import androidx.media3.common.MimeTypes; 32 33 import java.io.IOException; 34 35 /** Utilities for Media Editing tests. */ 36 public final class MediaEditingUtil { 37 38 public static final String MP4_ASSET_H264_WITH_INCREASING_TIMESTAMPS_1920W_1080H_1S_URI_STRING = 39 "sample_with_increasing_timestamps_1920x1080_30fps_avc.mp4"; 40 41 /** Baseline profile level 3.0 H.264 stream, which should be supported on all devices. */ 42 public static final String MP4_ASSET_H264_WITH_INCREASING_TIMESTAMPS_320W_240H_5S_URI_STRING = 43 "sample_with_increasing_timestamps_320x240_30fps_avc.mp4"; 44 45 public static final String MP4_ASSET_H264_WITH_INCREASING_TIMESTAMPS_642W_642H_3S_URI_STRING = 46 "bbb_642x642_1mbps_30fps_avc.mp4"; 47 48 public static final String MKV_ASSET_H264_340W_280H_10BIT = 49 "cosmat_340x280_24fps_crf22_avc_10bit.mkv"; 50 public static final Format MKV_ASSET_H264_340W_280H_10BIT_FORMAT = 51 new Format.Builder() 52 .setSampleMimeType(VIDEO_H264) 53 .setWidth(340) 54 .setHeight(280) 55 .setFrameRate(24f) 56 .setColorInfo( 57 new ColorInfo.Builder() 58 .setColorSpace(C.COLOR_SPACE_BT2020) 59 .setColorRange(C.COLOR_RANGE_LIMITED) 60 .setColorTransfer(C.COLOR_TRANSFER_HLG) 61 .build()) 62 .setCodecs("avc1.6E000D") 63 .build(); 64 65 public static final String MKV_ASSET_H264_520W_390H_10BIT = 66 "cosmat_520x390_24fps_crf22_avc_10bit.mkv"; 67 public static final Format MKV_ASSET_H264_520W_390H_10BIT_FORMAT = 68 new Format.Builder() 69 .setSampleMimeType(VIDEO_H264) 70 .setWidth(520) 71 .setHeight(390) 72 .setFrameRate(24f) 73 .setColorInfo( 74 new ColorInfo.Builder() 75 .setColorSpace(C.COLOR_SPACE_BT2020) 76 .setColorRange(C.COLOR_RANGE_LIMITED) 77 .setColorTransfer(C.COLOR_TRANSFER_HLG) 78 .build()) 79 .setCodecs("avc1.6E0016") 80 .build(); 81 82 public static final String MKV_ASSET_H264_640W_360H_10BIT = 83 "cosmat_640x360_24fps_crf22_avc_10bit_nob.mkv"; 84 public static final Format MKV_ASSET_H264_640W_360H_10BIT_FORMAT = 85 new Format.Builder() 86 .setSampleMimeType(VIDEO_H264) 87 .setWidth(640) 88 .setHeight(360) 89 .setFrameRate(24f) 90 .setColorInfo( 91 new ColorInfo.Builder() 92 .setColorSpace(C.COLOR_SPACE_BT2020) 93 .setColorRange(C.COLOR_RANGE_LIMITED) 94 .setColorTransfer(C.COLOR_TRANSFER_HLG) 95 .build()) 96 .setCodecs("avc1.6E001E") 97 .build(); 98 99 public static final String MKV_ASSET_H264_800W_640H_10BIT = 100 "cosmat_800x640_24fps_crf22_avc_10bit_nob.mkv"; 101 public static final Format MKV_ASSET_H264_800W_640H_10BIT_FORMAT = 102 new Format.Builder() 103 .setSampleMimeType(VIDEO_H264) 104 .setWidth(800) 105 .setHeight(640) 106 .setFrameRate(24f) 107 .setColorInfo( 108 new ColorInfo.Builder() 109 .setColorSpace(C.COLOR_SPACE_BT2020) 110 .setColorRange(C.COLOR_RANGE_LIMITED) 111 .setColorTransfer(C.COLOR_TRANSFER_HLG) 112 .build()) 113 .setCodecs("avc1.6E001F") 114 .build(); 115 116 public static final String MKV_ASSET_H264_1280W_720H_10BIT = 117 "cosmat_1280x720_24fps_crf22_avc_10bit_nob.mkv"; 118 public static final Format MKV_ASSET_H264_1280W_720H_HDR10_FORMAT = 119 new Format.Builder() 120 .setSampleMimeType(VIDEO_H264) 121 .setWidth(1280) 122 .setHeight(720) 123 .setFrameRate(24f) 124 .setColorInfo( 125 new ColorInfo.Builder() 126 .setColorSpace(C.COLOR_SPACE_BT2020) 127 .setColorRange(C.COLOR_RANGE_LIMITED) 128 .setColorTransfer(C.COLOR_TRANSFER_HLG) 129 .build()) 130 .setCodecs("avc1.6E001F") 131 .build(); 132 133 public static final String MP4_ASSET_HEVC_WITH_INCREASING_TIMESTAMPS_1920_1080_1S_URI_STRING = 134 "bbb_1920x1080_30fps_hevc_main_l40.mp4"; 135 136 public static final String MP4_ASSET_HEVC_WITH_INCREASING_TIMESTAMPS_720W_480H_1S_URI_STRING = 137 "bbb_720x480_30fps_hevc_main_l3.mp4"; 138 139 public static final String MP4_ASSET_HEVC_WITH_INCREASING_TIMESTAMPS_642W_642H_3S_URI_STRING = 140 "bbb_642x642_768kbps_30fps_hevc.mp4"; 141 142 public static final String MKV_ASSET_HEVC_340W_280H_5S_10BIT = 143 "cosmat_340x280_24fps_crf22_hevc_10bit.mkv"; 144 public static final Format MKV_ASSET_HEVC_340W_280H_10BIT_FORMAT = 145 new Format.Builder() 146 .setSampleMimeType(VIDEO_H265) 147 .setWidth(340) 148 .setHeight(280) 149 .setFrameRate(24f) 150 .setColorInfo( 151 new ColorInfo.Builder() 152 .setColorSpace(C.COLOR_SPACE_BT2020) 153 .setColorRange(C.COLOR_RANGE_LIMITED) 154 .setColorTransfer(C.COLOR_TRANSFER_HLG) 155 .build()) 156 .setCodecs("hvc1.2.4.L60.90") 157 .build(); 158 159 public static final String MKV_ASSET_HEVC_520W_390H_5S_10BIT = 160 "cosmat_520x390_24fps_crf22_hevc_10bit.mkv"; 161 public static final Format MKV_ASSET_HEVC_520W_390H_10BIT_FORMAT = 162 new Format.Builder() 163 .setSampleMimeType(VIDEO_H265) 164 .setWidth(520) 165 .setHeight(390) 166 .setFrameRate(24f) 167 .setColorInfo( 168 new ColorInfo.Builder() 169 .setColorSpace(C.COLOR_SPACE_BT2020) 170 .setColorRange(C.COLOR_RANGE_LIMITED) 171 .setColorTransfer(C.COLOR_TRANSFER_HLG) 172 .build()) 173 .setCodecs("hvc1.2.4.L63.90") 174 .build(); 175 176 public static final String MKV_ASSET_HEVC_640W_360H_5S_10BIT = 177 "cosmat_640x360_24fps_crf22_hevc_10bit_nob.mkv"; 178 public static final Format MKV_ASSET_HEVC_640W_360H_10BIT_FORMAT = 179 new Format.Builder() 180 .setSampleMimeType(VIDEO_H265) 181 .setWidth(640) 182 .setHeight(360) 183 .setFrameRate(24f) 184 .setColorInfo( 185 new ColorInfo.Builder() 186 .setColorSpace(C.COLOR_SPACE_BT2020) 187 .setColorRange(C.COLOR_RANGE_LIMITED) 188 .setColorTransfer(C.COLOR_TRANSFER_HLG) 189 .build()) 190 .setCodecs("hvc1.2.4.L63.90") 191 .build(); 192 193 public static final String MKV_ASSET_HEVC_800W_640H_5S_10BIT = 194 "cosmat_800x640_24fps_crf22_hevc_10bit_nob.mkv"; 195 public static final Format MKV_ASSET_HEVC_800W_640H_10BIT_FORMAT = 196 new Format.Builder() 197 .setSampleMimeType(VIDEO_H265) 198 .setWidth(800) 199 .setHeight(640) 200 .setFrameRate(24f) 201 .setColorInfo( 202 new ColorInfo.Builder() 203 .setColorSpace(C.COLOR_SPACE_BT2020) 204 .setColorRange(C.COLOR_RANGE_LIMITED) 205 .setColorTransfer(C.COLOR_TRANSFER_HLG) 206 .build()) 207 .setCodecs("hvc1.2.4.L90.90") 208 .build(); 209 210 public static final String MKV_ASSET_HEVC_1280W_720H_5S_10BIT = 211 "cosmat_1280x720_24fps_crf22_hevc_10bit_nob.mkv"; 212 public static final Format MKV_ASSET_HEVC_1280W_720H_10BIT_FORMAT = 213 new Format.Builder() 214 .setSampleMimeType(VIDEO_H265) 215 .setWidth(1280) 216 .setHeight(720) 217 .setFrameRate(24f) 218 .setColorInfo( 219 new ColorInfo.Builder() 220 .setColorSpace(C.COLOR_SPACE_BT2020) 221 .setColorRange(C.COLOR_RANGE_LIMITED) 222 .setColorTransfer(C.COLOR_TRANSFER_HLG) 223 .build()) 224 .setCodecs("hvc1.2.4.L93.90") 225 .build(); 226 227 /** 228 * Returns the {@link Format} of the given test asset. 229 * 230 * @param uri The string {@code uri} to the test file. The {@code uri} must be defined in this 231 * file. 232 * @throws IllegalArgumentException If the given {@code uri} is not defined in this file. 233 */ getFormatForTestFile(String uri)234 public static Format getFormatForTestFile(String uri) { 235 switch (uri) { 236 case MKV_ASSET_H264_340W_280H_10BIT: 237 return MKV_ASSET_H264_340W_280H_10BIT_FORMAT; 238 case MKV_ASSET_H264_520W_390H_10BIT: 239 return MKV_ASSET_H264_520W_390H_10BIT_FORMAT; 240 case MKV_ASSET_H264_640W_360H_10BIT: 241 return MKV_ASSET_H264_640W_360H_10BIT_FORMAT; 242 case MKV_ASSET_H264_800W_640H_10BIT: 243 return MKV_ASSET_H264_800W_640H_10BIT_FORMAT; 244 case MKV_ASSET_H264_1280W_720H_10BIT: 245 return MKV_ASSET_H264_1280W_720H_HDR10_FORMAT; 246 case MKV_ASSET_HEVC_340W_280H_5S_10BIT: 247 return MKV_ASSET_HEVC_340W_280H_10BIT_FORMAT; 248 case MKV_ASSET_HEVC_520W_390H_5S_10BIT: 249 return MKV_ASSET_HEVC_520W_390H_10BIT_FORMAT; 250 case MKV_ASSET_HEVC_640W_360H_5S_10BIT: 251 return MKV_ASSET_HEVC_640W_360H_10BIT_FORMAT; 252 case MKV_ASSET_HEVC_800W_640H_5S_10BIT: 253 return MKV_ASSET_HEVC_800W_640H_10BIT_FORMAT; 254 case MKV_ASSET_HEVC_1280W_720H_5S_10BIT: 255 return MKV_ASSET_HEVC_1280W_720H_10BIT_FORMAT; 256 default: 257 throw new IllegalArgumentException("The format for the given uri is not found."); 258 } 259 } 260 261 public static final String MP4_ASSET_HEVC_WITH_INCREASING_TIMESTAMPS_608W_1080H_4S_URI_STRING = 262 "video_decode_accuracy_and_capability-hevc_608x1080_30fps.mp4"; 263 getMuxedWidthHeight(String filePath)264 public static Format getMuxedWidthHeight(String filePath) throws IOException { 265 MediaExtractor mediaExtractor = new MediaExtractor(); 266 mediaExtractor.setDataSource(filePath); 267 @Nullable MediaFormat mediaFormat = null; 268 for (int i = 0; i < mediaExtractor.getTrackCount(); i++) { 269 if (MimeTypes.isVideo(mediaExtractor.getTrackFormat(i).getString(MediaFormat.KEY_MIME))) { 270 mediaFormat = mediaExtractor.getTrackFormat(i); 271 mediaExtractor.selectTrack(i); 272 break; 273 } 274 } 275 276 checkStateNotNull(mediaFormat); 277 checkState(mediaFormat.containsKey(MediaFormat.KEY_WIDTH)); 278 checkState(mediaFormat.containsKey(MediaFormat.KEY_HEIGHT)); 279 280 int rotationDegree = 0; 281 if (mediaFormat.containsKey(MediaFormat.KEY_ROTATION)) { 282 rotationDegree = mediaFormat.getInteger(MediaFormat.KEY_ROTATION); 283 } 284 return new Format.Builder() 285 .setWidth(mediaFormat.getInteger(MediaFormat.KEY_WIDTH)) 286 .setHeight(mediaFormat.getInteger(MediaFormat.KEY_HEIGHT)) 287 .setRotationDegrees(rotationDegree) 288 .build(); 289 } 290 getMuxedOutputProfile(String filePath)291 public static int getMuxedOutputProfile(String filePath) throws IOException { 292 MediaExtractor mediaExtractor = new MediaExtractor(); 293 mediaExtractor.setDataSource(filePath); 294 @Nullable MediaFormat mediaFormat = null; 295 for (int i = 0; i < mediaExtractor.getTrackCount(); i++) { 296 if (MimeTypes.isVideo(mediaExtractor.getTrackFormat(i).getString(MediaFormat.KEY_MIME))) { 297 mediaFormat = mediaExtractor.getTrackFormat(i); 298 mediaExtractor.selectTrack(i); 299 break; 300 } 301 } 302 303 checkStateNotNull(mediaFormat); 304 checkState(mediaFormat.containsKey(MediaFormat.KEY_PROFILE)); 305 return mediaFormat.getInteger(MediaFormat.KEY_PROFILE, -1); 306 } 307 } 308