1 /* 2 * Copyright (C) 2009 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "Utils" 19 #include <utils/Log.h> 20 #include <ctype.h> 21 #include <stdio.h> 22 #include <sys/stat.h> 23 24 #include <utility> 25 #include <vector> 26 27 #include "include/ESDS.h" 28 #include "include/HevcUtils.h" 29 30 #include <cutils/properties.h> 31 #include <media/openmax/OMX_Audio.h> 32 #include <media/openmax/OMX_Video.h> 33 #include <media/openmax/OMX_VideoExt.h> 34 #include <media/stagefright/CodecBase.h> 35 #include <media/stagefright/foundation/ABuffer.h> 36 #include <media/stagefright/foundation/ADebug.h> 37 #include <media/stagefright/foundation/ALookup.h> 38 #include <media/stagefright/foundation/AMessage.h> 39 #include <media/stagefright/foundation/ByteUtils.h> 40 #include <media/stagefright/foundation/OpusHeader.h> 41 #include <media/stagefright/MetaData.h> 42 #include <media/stagefright/MediaCodecConstants.h> 43 #include <media/stagefright/MediaDefs.h> 44 #include <media/AudioSystem.h> 45 #include <media/MediaPlayerInterface.h> 46 #include <media/stagefright/Utils.h> 47 #include <media/AudioParameter.h> 48 #include <system/audio.h> 49 50 namespace android { 51 52 static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) { 53 if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) { 54 sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024); 55 if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) { 56 return NO_MEMORY; 57 } 58 memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size()); 59 tmpBuffer->setRange(0, (*buffer)->size()); 60 (*buffer) = tmpBuffer; 61 } 62 63 memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4); 64 memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length); 65 (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length); 66 return OK; 67 } 68 69 #if 0 70 static void convertMetaDataToMessageInt32( 71 const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) { 72 int32_t value; 73 if (meta->findInt32(key, &value)) { 74 msg->setInt32(name, value); 75 } 76 } 77 #endif 78 79 static void convertMetaDataToMessageColorAspects(const MetaDataBase *meta, sp<AMessage> &msg) { 80 // 0 values are unspecified 81 int32_t range = 0; 82 int32_t primaries = 0; 83 int32_t transferFunction = 0; 84 int32_t colorMatrix = 0; 85 meta->findInt32(kKeyColorRange, &range); 86 meta->findInt32(kKeyColorPrimaries, &primaries); 87 meta->findInt32(kKeyTransferFunction, &transferFunction); 88 meta->findInt32(kKeyColorMatrix, &colorMatrix); 89 ColorAspects colorAspects; 90 memset(&colorAspects, 0, sizeof(colorAspects)); 91 colorAspects.mRange = (ColorAspects::Range)range; 92 colorAspects.mPrimaries = (ColorAspects::Primaries)primaries; 93 colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction; 94 colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix; 95 96 int32_t rangeMsg, standardMsg, transferMsg; 97 if (CodecBase::convertCodecColorAspectsToPlatformAspects( 98 colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) { 99 return; 100 } 101 102 // save specified values to msg 103 if (rangeMsg != 0) { 104 msg->setInt32("color-range", rangeMsg); 105 } 106 if (standardMsg != 0) { 107 msg->setInt32("color-standard", standardMsg); 108 } 109 if (transferMsg != 0) { 110 msg->setInt32("color-transfer", transferMsg); 111 } 112 } 113 114 static bool isHdr(const sp<AMessage> &format) { 115 // if CSD specifies HDR transfer(s), we assume HDR. Otherwise, if it specifies non-HDR 116 // transfers, we must assume non-HDR. This is because CSD trumps any color-transfer key 117 // in the format. 118 int32_t isHdr; 119 if (format->findInt32("android._is-hdr", &isHdr)) { 120 return isHdr; 121 } 122 123 // if user/container supplied HDR static info without transfer set, assume true 124 if ((format->contains("hdr-static-info") || format->contains("hdr10-plus-info")) 125 && !format->contains("color-transfer")) { 126 return true; 127 } 128 // otherwise, verify that an HDR transfer function is set 129 int32_t transfer; 130 if (format->findInt32("color-transfer", &transfer)) { 131 return transfer == ColorUtils::kColorTransferST2084 132 || transfer == ColorUtils::kColorTransferHLG; 133 } 134 return false; 135 } 136 137 static void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) { 138 if (csd->size() < 2) { 139 return; 140 } 141 142 uint16_t audioObjectType = U16_AT((uint8_t*)csd->data()); 143 if ((audioObjectType & 0xF800) == 0xF800) { 144 audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F); 145 } else { 146 audioObjectType >>= 11; 147 } 148 149 const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles { 150 { 1, OMX_AUDIO_AACObjectMain }, 151 { 2, OMX_AUDIO_AACObjectLC }, 152 { 3, OMX_AUDIO_AACObjectSSR }, 153 { 4, OMX_AUDIO_AACObjectLTP }, 154 { 5, OMX_AUDIO_AACObjectHE }, 155 { 6, OMX_AUDIO_AACObjectScalable }, 156 { 17, OMX_AUDIO_AACObjectERLC }, 157 { 23, OMX_AUDIO_AACObjectLD }, 158 { 29, OMX_AUDIO_AACObjectHE_PS }, 159 { 39, OMX_AUDIO_AACObjectELD }, 160 { 42, OMX_AUDIO_AACObjectXHE }, 161 }; 162 163 OMX_AUDIO_AACPROFILETYPE profile; 164 if (profiles.map(audioObjectType, &profile)) { 165 format->setInt32("profile", profile); 166 } 167 } 168 169 static void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) { 170 if (size < 4 || ptr[0] != 1) { // configurationVersion == 1 171 return; 172 } 173 const uint8_t profile = ptr[1]; 174 const uint8_t constraints = ptr[2]; 175 const uint8_t level = ptr[3]; 176 177 const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels { 178 { 9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles 179 { 10, OMX_VIDEO_AVCLevel1 }, 180 { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11 181 { 11, OMX_VIDEO_AVCLevel1b }, 182 { 12, OMX_VIDEO_AVCLevel12 }, 183 { 13, OMX_VIDEO_AVCLevel13 }, 184 { 20, OMX_VIDEO_AVCLevel2 }, 185 { 21, OMX_VIDEO_AVCLevel21 }, 186 { 22, OMX_VIDEO_AVCLevel22 }, 187 { 30, OMX_VIDEO_AVCLevel3 }, 188 { 31, OMX_VIDEO_AVCLevel31 }, 189 { 32, OMX_VIDEO_AVCLevel32 }, 190 { 40, OMX_VIDEO_AVCLevel4 }, 191 { 41, OMX_VIDEO_AVCLevel41 }, 192 { 42, OMX_VIDEO_AVCLevel42 }, 193 { 50, OMX_VIDEO_AVCLevel5 }, 194 { 51, OMX_VIDEO_AVCLevel51 }, 195 { 52, OMX_VIDEO_AVCLevel52 }, 196 { 60, OMX_VIDEO_AVCLevel6 }, 197 { 61, OMX_VIDEO_AVCLevel61 }, 198 { 62, OMX_VIDEO_AVCLevel62 }, 199 }; 200 const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles { 201 { 66, OMX_VIDEO_AVCProfileBaseline }, 202 { 77, OMX_VIDEO_AVCProfileMain }, 203 { 88, OMX_VIDEO_AVCProfileExtended }, 204 { 100, OMX_VIDEO_AVCProfileHigh }, 205 { 110, OMX_VIDEO_AVCProfileHigh10 }, 206 { 122, OMX_VIDEO_AVCProfileHigh422 }, 207 { 244, OMX_VIDEO_AVCProfileHigh444 }, 208 }; 209 210 // set profile & level if they are recognized 211 OMX_VIDEO_AVCPROFILETYPE codecProfile; 212 OMX_VIDEO_AVCLEVELTYPE codecLevel; 213 if (profiles.map(profile, &codecProfile)) { 214 if (profile == 66 && (constraints & 0x40)) { 215 codecProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline; 216 } else if (profile == 100 && (constraints & 0x0C) == 0x0C) { 217 codecProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh; 218 } 219 format->setInt32("profile", codecProfile); 220 if (levels.map(level, &codecLevel)) { 221 // for 9 && 11 decide level based on profile and constraint_set3 flag 222 if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) { 223 codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11; 224 } 225 format->setInt32("level", codecLevel); 226 } 227 } 228 } 229 230 static void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) { 231 if (size < 7) { 232 return; 233 } 234 235 const uint8_t profile = ptr[6]; 236 const uint8_t level = ptr[5]; 237 238 const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles { 239 { 0, OMX_VIDEO_H263ProfileBaseline }, 240 { 1, OMX_VIDEO_H263ProfileH320Coding }, 241 { 2, OMX_VIDEO_H263ProfileBackwardCompatible }, 242 { 3, OMX_VIDEO_H263ProfileISWV2 }, 243 { 4, OMX_VIDEO_H263ProfileISWV3 }, 244 { 5, OMX_VIDEO_H263ProfileHighCompression }, 245 { 6, OMX_VIDEO_H263ProfileInternet }, 246 { 7, OMX_VIDEO_H263ProfileInterlace }, 247 { 8, OMX_VIDEO_H263ProfileHighLatency }, 248 }; 249 250 const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels { 251 { 10, OMX_VIDEO_H263Level10 }, 252 { 20, OMX_VIDEO_H263Level20 }, 253 { 30, OMX_VIDEO_H263Level30 }, 254 { 40, OMX_VIDEO_H263Level40 }, 255 { 45, OMX_VIDEO_H263Level45 }, 256 { 50, OMX_VIDEO_H263Level50 }, 257 { 60, OMX_VIDEO_H263Level60 }, 258 { 70, OMX_VIDEO_H263Level70 }, 259 }; 260 261 // set profile & level if they are recognized 262 OMX_VIDEO_H263PROFILETYPE codecProfile; 263 OMX_VIDEO_H263LEVELTYPE codecLevel; 264 if (profiles.map(profile, &codecProfile)) { 265 format->setInt32("profile", codecProfile); 266 if (levels.map(level, &codecLevel)) { 267 format->setInt32("level", codecLevel); 268 } 269 } 270 } 271 272 static void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) { 273 if (size < 13 || ptr[0] != 1) { // configurationVersion == 1 274 return; 275 } 276 277 const uint8_t profile = ptr[1] & 0x1F; 278 const uint8_t tier = (ptr[1] & 0x20) >> 5; 279 const uint8_t level = ptr[12]; 280 281 const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels { 282 { { 0, 30 }, OMX_VIDEO_HEVCMainTierLevel1 }, 283 { { 0, 60 }, OMX_VIDEO_HEVCMainTierLevel2 }, 284 { { 0, 63 }, OMX_VIDEO_HEVCMainTierLevel21 }, 285 { { 0, 90 }, OMX_VIDEO_HEVCMainTierLevel3 }, 286 { { 0, 93 }, OMX_VIDEO_HEVCMainTierLevel31 }, 287 { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4 }, 288 { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 }, 289 { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5 }, 290 { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 }, 291 { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 }, 292 { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6 }, 293 { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 }, 294 { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 }, 295 { { 1, 30 }, OMX_VIDEO_HEVCHighTierLevel1 }, 296 { { 1, 60 }, OMX_VIDEO_HEVCHighTierLevel2 }, 297 { { 1, 63 }, OMX_VIDEO_HEVCHighTierLevel21 }, 298 { { 1, 90 }, OMX_VIDEO_HEVCHighTierLevel3 }, 299 { { 1, 93 }, OMX_VIDEO_HEVCHighTierLevel31 }, 300 { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4 }, 301 { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 }, 302 { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5 }, 303 { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 }, 304 { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 }, 305 { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6 }, 306 { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 }, 307 { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 }, 308 }; 309 310 const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles { 311 { 1, OMX_VIDEO_HEVCProfileMain }, 312 { 2, OMX_VIDEO_HEVCProfileMain10 }, 313 // use Main for Main Still Picture decoding 314 { 3, OMX_VIDEO_HEVCProfileMain }, 315 }; 316 317 // set profile & level if they are recognized 318 OMX_VIDEO_HEVCPROFILETYPE codecProfile; 319 OMX_VIDEO_HEVCLEVELTYPE codecLevel; 320 if (!profiles.map(profile, &codecProfile)) { 321 if (ptr[2] & 0x40 /* general compatibility flag 1 */) { 322 // Note that this case covers Main Still Picture too 323 codecProfile = OMX_VIDEO_HEVCProfileMain; 324 } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) { 325 codecProfile = OMX_VIDEO_HEVCProfileMain10; 326 } else { 327 return; 328 } 329 } 330 331 // bump to HDR profile 332 if (isHdr(format) && codecProfile == OMX_VIDEO_HEVCProfileMain10) { 333 codecProfile = OMX_VIDEO_HEVCProfileMain10HDR10; 334 } 335 336 format->setInt32("profile", codecProfile); 337 if (levels.map(std::make_pair(tier, level), &codecLevel)) { 338 format->setInt32("level", codecLevel); 339 } 340 } 341 342 static void parseMpeg2ProfileLevelFromHeader( 343 const uint8_t *data, size_t size, sp<AMessage> &format) { 344 // find sequence extension 345 const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4); 346 if (seq != NULL && seq + 5 < data + size) { 347 const uint8_t start_code = seq[4] >> 4; 348 if (start_code != 1 /* sequence extension ID */) { 349 return; 350 } 351 const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4); 352 353 const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles { 354 { 0x50, OMX_VIDEO_MPEG2ProfileSimple }, 355 { 0x40, OMX_VIDEO_MPEG2ProfileMain }, 356 { 0x30, OMX_VIDEO_MPEG2ProfileSNR }, 357 { 0x20, OMX_VIDEO_MPEG2ProfileSpatial }, 358 { 0x10, OMX_VIDEO_MPEG2ProfileHigh }, 359 }; 360 361 const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels { 362 { 0x0A, OMX_VIDEO_MPEG2LevelLL }, 363 { 0x08, OMX_VIDEO_MPEG2LevelML }, 364 { 0x06, OMX_VIDEO_MPEG2LevelH14 }, 365 { 0x04, OMX_VIDEO_MPEG2LevelHL }, 366 { 0x02, OMX_VIDEO_MPEG2LevelHP }, 367 }; 368 369 const static ALookup<uint8_t, 370 std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes { 371 /* unsupported 372 { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL } }, 373 { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML } }, 374 { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } }, 375 { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL } }, */ 376 { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML } }, 377 { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL } }, 378 }; 379 380 OMX_VIDEO_MPEG2PROFILETYPE profile; 381 OMX_VIDEO_MPEG2LEVELTYPE level; 382 std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel; 383 if (escapes.map(indication, &profileLevel)) { 384 format->setInt32("profile", profileLevel.first); 385 format->setInt32("level", profileLevel.second); 386 } else if (profiles.map(indication & 0x70, &profile)) { 387 format->setInt32("profile", profile); 388 if (levels.map(indication & 0xF, &level)) { 389 format->setInt32("level", level); 390 } 391 } 392 } 393 } 394 395 static void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) { 396 // esds seems to only contain the profile for MPEG-2 397 uint8_t objType; 398 if (esds.getObjectTypeIndication(&objType) == OK) { 399 const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{ 400 { 0x60, OMX_VIDEO_MPEG2ProfileSimple }, 401 { 0x61, OMX_VIDEO_MPEG2ProfileMain }, 402 { 0x62, OMX_VIDEO_MPEG2ProfileSNR }, 403 { 0x63, OMX_VIDEO_MPEG2ProfileSpatial }, 404 { 0x64, OMX_VIDEO_MPEG2ProfileHigh }, 405 { 0x65, OMX_VIDEO_MPEG2Profile422 }, 406 }; 407 408 OMX_VIDEO_MPEG2PROFILETYPE profile; 409 if (profiles.map(objType, &profile)) { 410 format->setInt32("profile", profile); 411 } 412 } 413 } 414 415 static void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) { 416 const uint8_t *data = csd->data(); 417 // find visual object sequence 418 const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4); 419 if (seq != NULL && seq + 4 < data + csd->size()) { 420 const uint8_t indication = seq[4]; 421 422 const static ALookup<uint8_t, 423 std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table { 424 { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1 } }, 425 { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2 } }, 426 { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3 } }, 427 { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a } }, 428 { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5 } }, 429 { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level6 } }, 430 { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0 } }, 431 { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b } }, 432 { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_MPEG4Level0 } }, 433 { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_MPEG4Level1 } }, 434 { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_MPEG4Level2 } }, 435 /* unsupported 436 { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER, OMX_VIDEO_MPEG4Level0 } }, 437 { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER, OMX_VIDEO_MPEG4Level1 } }, 438 { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER, OMX_VIDEO_MPEG4Level2 } }, */ 439 { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level1 } }, 440 { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2 } }, 441 { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level2 } }, 442 { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level3 } }, 443 { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level4 } }, 444 /* deprecated 445 { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit, OMX_VIDEO_MPEG4Level2 } }, */ 446 { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture, OMX_VIDEO_MPEG4Level1 } }, 447 { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level1 } }, 448 { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level2 } }, 449 { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA, OMX_VIDEO_MPEG4Level1 } }, 450 { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA, OMX_VIDEO_MPEG4Level2 } }, 451 { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level1 } }, 452 { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level2 } }, 453 { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level1 } }, 454 { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level2 } }, 455 { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level1 } }, 456 { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level2 } }, 457 { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level3 } }, 458 { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level4 } }, 459 { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level1 } }, 460 { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level2 } }, 461 { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level3 } }, 462 { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level1 } }, 463 { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level2 } }, 464 { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level3 } }, 465 { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level4 } }, 466 { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level1 } }, 467 { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level2 } }, 468 { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level1 } }, 469 { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level2 } }, 470 { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level3 } }, 471 /* unsupported 472 { 0b11100001, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level1 } }, 473 { 0b11100010, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level2 } }, 474 { 0b11100011, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level3 } }, 475 { 0b11100100, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level4 } }, 476 { 0b11100101, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level1 } }, 477 { 0b11100110, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level2 } }, 478 { 0b11100111, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level3 } }, 479 { 0b11101000, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level4 } }, 480 { 0b11101011, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level5 } }, 481 { 0b11101100, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level6 } }, */ 482 { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0 } }, 483 { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1 } }, 484 { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2 } }, 485 { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3 } }, 486 { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4 } }, 487 { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5 } }, 488 { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3b } }, 489 /* deprecated 490 { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0 } }, 491 { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1 } }, 492 { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2 } }, 493 { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3 } }, 494 { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4 } }, 495 { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5 } }, */ 496 }; 497 498 std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel; 499 if (table.map(indication, &profileLevel)) { 500 format->setInt32("profile", profileLevel.first); 501 format->setInt32("level", profileLevel.second); 502 } 503 } 504 } 505 506 static void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) { 507 const uint8_t *data = csd->data(); 508 size_t remaining = csd->size(); 509 510 while (remaining >= 2) { 511 const uint8_t id = data[0]; 512 const uint8_t length = data[1]; 513 remaining -= 2; 514 data += 2; 515 if (length > remaining) { 516 break; 517 } 518 switch (id) { 519 case 1 /* profileId */: 520 if (length >= 1) { 521 const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles { 522 { 0, OMX_VIDEO_VP9Profile0 }, 523 { 1, OMX_VIDEO_VP9Profile1 }, 524 { 2, OMX_VIDEO_VP9Profile2 }, 525 { 3, OMX_VIDEO_VP9Profile3 }, 526 }; 527 528 const static ALookup<OMX_VIDEO_VP9PROFILETYPE, OMX_VIDEO_VP9PROFILETYPE> toHdr { 529 { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Profile2HDR }, 530 { OMX_VIDEO_VP9Profile3, OMX_VIDEO_VP9Profile3HDR }, 531 }; 532 533 OMX_VIDEO_VP9PROFILETYPE profile; 534 if (profiles.map(data[0], &profile)) { 535 // convert to HDR profile 536 if (isHdr(format)) { 537 toHdr.lookup(profile, &profile); 538 } 539 540 format->setInt32("profile", profile); 541 } 542 } 543 break; 544 case 2 /* levelId */: 545 if (length >= 1) { 546 const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels { 547 { 10, OMX_VIDEO_VP9Level1 }, 548 { 11, OMX_VIDEO_VP9Level11 }, 549 { 20, OMX_VIDEO_VP9Level2 }, 550 { 21, OMX_VIDEO_VP9Level21 }, 551 { 30, OMX_VIDEO_VP9Level3 }, 552 { 31, OMX_VIDEO_VP9Level31 }, 553 { 40, OMX_VIDEO_VP9Level4 }, 554 { 41, OMX_VIDEO_VP9Level41 }, 555 { 50, OMX_VIDEO_VP9Level5 }, 556 { 51, OMX_VIDEO_VP9Level51 }, 557 { 52, OMX_VIDEO_VP9Level52 }, 558 { 60, OMX_VIDEO_VP9Level6 }, 559 { 61, OMX_VIDEO_VP9Level61 }, 560 { 62, OMX_VIDEO_VP9Level62 }, 561 }; 562 563 OMX_VIDEO_VP9LEVELTYPE level; 564 if (levels.map(data[0], &level)) { 565 format->setInt32("level", level); 566 } 567 } 568 break; 569 default: 570 break; 571 } 572 remaining -= length; 573 data += length; 574 } 575 } 576 577 static void parseAV1ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) { 578 // Parse CSD structure to extract profile level information 579 // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox 580 const uint8_t *data = csd->data(); 581 size_t remaining = csd->size(); 582 if (remaining < 4 || data[0] != 0x81) { // configurationVersion == 1 583 return; 584 } 585 uint8_t profileData = (data[1] & 0xE0) >> 5; 586 uint8_t levelData = data[1] & 0x1F; 587 uint8_t highBitDepth = (data[2] & 0x40) >> 6; 588 589 const static ALookup<std::pair<uint8_t, uint8_t>, int32_t> profiles { 590 { { 0, 0 }, AV1ProfileMain8 }, 591 { { 1, 0 }, AV1ProfileMain10 }, 592 }; 593 594 int32_t profile; 595 if (profiles.map(std::make_pair(highBitDepth, profileData), &profile)) { 596 // bump to HDR profile 597 if (isHdr(format) && profile == AV1ProfileMain10) { 598 if (format->contains("hdr10-plus-info")) { 599 profile = AV1ProfileMain10HDR10Plus; 600 } else { 601 profile = AV1ProfileMain10HDR10; 602 } 603 } 604 format->setInt32("profile", profile); 605 } 606 const static ALookup<uint8_t, int32_t> levels { 607 { 0, AV1Level2 }, 608 { 1, AV1Level21 }, 609 { 2, AV1Level22 }, 610 { 3, AV1Level23 }, 611 { 4, AV1Level3 }, 612 { 5, AV1Level31 }, 613 { 6, AV1Level32 }, 614 { 7, AV1Level33 }, 615 { 8, AV1Level4 }, 616 { 9, AV1Level41 }, 617 { 10, AV1Level42 }, 618 { 11, AV1Level43 }, 619 { 12, AV1Level5 }, 620 { 13, AV1Level51 }, 621 { 14, AV1Level52 }, 622 { 15, AV1Level53 }, 623 { 16, AV1Level6 }, 624 { 17, AV1Level61 }, 625 { 18, AV1Level62 }, 626 { 19, AV1Level63 }, 627 { 20, AV1Level7 }, 628 { 21, AV1Level71 }, 629 { 22, AV1Level72 }, 630 { 23, AV1Level73 }, 631 }; 632 633 int32_t level; 634 if (levels.map(levelData, &level)) { 635 format->setInt32("level", level); 636 } 637 } 638 639 640 static std::vector<std::pair<const char *, uint32_t>> stringMappings { 641 { 642 { "album", kKeyAlbum }, 643 { "albumartist", kKeyAlbumArtist }, 644 { "artist", kKeyArtist }, 645 { "author", kKeyAuthor }, 646 { "cdtracknum", kKeyCDTrackNumber }, 647 { "compilation", kKeyCompilation }, 648 { "composer", kKeyComposer }, 649 { "date", kKeyDate }, 650 { "discnum", kKeyDiscNumber }, 651 { "genre", kKeyGenre }, 652 { "location", kKeyLocation }, 653 { "lyricist", kKeyWriter }, 654 { "manufacturer", kKeyManufacturer }, 655 { "title", kKeyTitle }, 656 { "year", kKeyYear }, 657 } 658 }; 659 660 static std::vector<std::pair<const char *, uint32_t>> floatMappings { 661 { 662 { "capture-rate", kKeyCaptureFramerate }, 663 } 664 }; 665 666 static std::vector<std::pair<const char *, uint32_t>> int64Mappings { 667 { 668 { "exif-offset", kKeyExifOffset }, 669 { "exif-size", kKeyExifSize }, 670 { "target-time", kKeyTargetTime }, 671 { "thumbnail-time", kKeyThumbnailTime }, 672 { "timeUs", kKeyTime }, 673 { "durationUs", kKeyDuration }, 674 } 675 }; 676 677 static std::vector<std::pair<const char *, uint32_t>> int32Mappings { 678 { 679 { "loop", kKeyAutoLoop }, 680 { "time-scale", kKeyTimeScale }, 681 { "crypto-mode", kKeyCryptoMode }, 682 { "crypto-default-iv-size", kKeyCryptoDefaultIVSize }, 683 { "crypto-encrypted-byte-block", kKeyEncryptedByteBlock }, 684 { "crypto-skip-byte-block", kKeySkipByteBlock }, 685 { "frame-count", kKeyFrameCount }, 686 { "max-bitrate", kKeyMaxBitRate }, 687 { "pcm-big-endian", kKeyPcmBigEndian }, 688 { "temporal-layer-count", kKeyTemporalLayerCount }, 689 { "temporal-layer-id", kKeyTemporalLayerId }, 690 { "thumbnail-width", kKeyThumbnailWidth }, 691 { "thumbnail-height", kKeyThumbnailHeight }, 692 { "valid-samples", kKeyValidSamples }, 693 } 694 }; 695 696 static std::vector<std::pair<const char *, uint32_t>> bufferMappings { 697 { 698 { "albumart", kKeyAlbumArt }, 699 { "audio-presentation-info", kKeyAudioPresentationInfo }, 700 { "pssh", kKeyPssh }, 701 { "crypto-iv", kKeyCryptoIV }, 702 { "crypto-key", kKeyCryptoKey }, 703 { "crypto-encrypted-sizes", kKeyEncryptedSizes }, 704 { "crypto-plain-sizes", kKeyPlainSizes }, 705 { "icc-profile", kKeyIccProfile }, 706 { "sei", kKeySEI }, 707 { "text-format-data", kKeyTextFormatData }, 708 { "thumbnail-csd-hevc", kKeyThumbnailHVCC }, 709 } 710 }; 711 712 static std::vector<std::pair<const char *, uint32_t>> CSDMappings { 713 { 714 { "csd-0", kKeyOpaqueCSD0 }, 715 { "csd-1", kKeyOpaqueCSD1 }, 716 { "csd-2", kKeyOpaqueCSD2 }, 717 } 718 }; 719 720 void convertMessageToMetaDataFromMappings(const sp<AMessage> &msg, sp<MetaData> &meta) { 721 for (auto elem : stringMappings) { 722 AString value; 723 if (msg->findString(elem.first, &value)) { 724 meta->setCString(elem.second, value.c_str()); 725 } 726 } 727 728 for (auto elem : floatMappings) { 729 float value; 730 if (msg->findFloat(elem.first, &value)) { 731 meta->setFloat(elem.second, value); 732 } 733 } 734 735 for (auto elem : int64Mappings) { 736 int64_t value; 737 if (msg->findInt64(elem.first, &value)) { 738 meta->setInt64(elem.second, value); 739 } 740 } 741 742 for (auto elem : int32Mappings) { 743 int32_t value; 744 if (msg->findInt32(elem.first, &value)) { 745 meta->setInt32(elem.second, value); 746 } 747 } 748 749 for (auto elem : bufferMappings) { 750 sp<ABuffer> value; 751 if (msg->findBuffer(elem.first, &value)) { 752 meta->setData(elem.second, 753 MetaDataBase::Type::TYPE_NONE, value->data(), value->size()); 754 } 755 } 756 757 for (auto elem : CSDMappings) { 758 sp<ABuffer> value; 759 if (msg->findBuffer(elem.first, &value)) { 760 meta->setData(elem.second, 761 MetaDataBase::Type::TYPE_NONE, value->data(), value->size()); 762 } 763 } 764 } 765 766 void convertMetaDataToMessageFromMappings(const MetaDataBase *meta, sp<AMessage> format) { 767 for (auto elem : stringMappings) { 768 const char *value; 769 if (meta->findCString(elem.second, &value)) { 770 format->setString(elem.first, value, strlen(value)); 771 } 772 } 773 774 for (auto elem : floatMappings) { 775 float value; 776 if (meta->findFloat(elem.second, &value)) { 777 format->setFloat(elem.first, value); 778 } 779 } 780 781 for (auto elem : int64Mappings) { 782 int64_t value; 783 if (meta->findInt64(elem.second, &value)) { 784 format->setInt64(elem.first, value); 785 } 786 } 787 788 for (auto elem : int32Mappings) { 789 int32_t value; 790 if (meta->findInt32(elem.second, &value)) { 791 format->setInt32(elem.first, value); 792 } 793 } 794 795 for (auto elem : bufferMappings) { 796 uint32_t type; 797 const void* data; 798 size_t size; 799 if (meta->findData(elem.second, &type, &data, &size)) { 800 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size); 801 format->setBuffer(elem.first, buf); 802 } 803 } 804 805 for (auto elem : CSDMappings) { 806 uint32_t type; 807 const void* data; 808 size_t size; 809 if (meta->findData(elem.second, &type, &data, &size)) { 810 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size); 811 buf->meta()->setInt32("csd", true); 812 buf->meta()->setInt64("timeUs", 0); 813 format->setBuffer(elem.first, buf); 814 } 815 } 816 } 817 818 status_t convertMetaDataToMessage( 819 const sp<MetaData> &meta, sp<AMessage> *format) { 820 return convertMetaDataToMessage(meta.get(), format); 821 } 822 823 status_t convertMetaDataToMessage( 824 const MetaDataBase *meta, sp<AMessage> *format) { 825 826 format->clear(); 827 828 if (meta == NULL) { 829 ALOGE("convertMetaDataToMessage: NULL input"); 830 return BAD_VALUE; 831 } 832 833 const char *mime; 834 if (!meta->findCString(kKeyMIMEType, &mime)) { 835 return BAD_VALUE; 836 } 837 838 sp<AMessage> msg = new AMessage; 839 msg->setString("mime", mime); 840 841 convertMetaDataToMessageFromMappings(meta, msg); 842 843 uint32_t type; 844 const void *data; 845 size_t size; 846 if (meta->findData(kKeyCASessionID, &type, &data, &size)) { 847 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 848 if (buffer.get() == NULL || buffer->base() == NULL) { 849 return NO_MEMORY; 850 } 851 852 msg->setBuffer("ca-session-id", buffer); 853 memcpy(buffer->data(), data, size); 854 } 855 856 if (meta->findData(kKeyCAPrivateData, &type, &data, &size)) { 857 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 858 if (buffer.get() == NULL || buffer->base() == NULL) { 859 return NO_MEMORY; 860 } 861 862 msg->setBuffer("ca-private-data", buffer); 863 memcpy(buffer->data(), data, size); 864 } 865 866 int32_t systemId; 867 if (meta->findInt32(kKeyCASystemID, &systemId)) { 868 msg->setInt32("ca-system-id", systemId); 869 } 870 871 if (!strncasecmp("video/scrambled", mime, 15) 872 || !strncasecmp("audio/scrambled", mime, 15)) { 873 874 *format = msg; 875 return OK; 876 } 877 878 int64_t durationUs; 879 if (meta->findInt64(kKeyDuration, &durationUs)) { 880 msg->setInt64("durationUs", durationUs); 881 } 882 883 int32_t avgBitRate = 0; 884 if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) { 885 msg->setInt32("bitrate", avgBitRate); 886 } 887 888 int32_t maxBitRate; 889 if (meta->findInt32(kKeyMaxBitRate, &maxBitRate) 890 && maxBitRate > 0 && maxBitRate >= avgBitRate) { 891 msg->setInt32("max-bitrate", maxBitRate); 892 } 893 894 int32_t isSync; 895 if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { 896 msg->setInt32("is-sync-frame", 1); 897 } 898 899 // this only needs to be translated from meta to message as it is an extractor key 900 int32_t trackID; 901 if (meta->findInt32(kKeyTrackID, &trackID)) { 902 msg->setInt32("track-id", trackID); 903 } 904 905 const char *lang; 906 if (meta->findCString(kKeyMediaLanguage, &lang)) { 907 msg->setString("language", lang); 908 } 909 910 if (!strncasecmp("video/", mime, 6) || 911 !strncasecmp("image/", mime, 6)) { 912 int32_t width, height; 913 if (!meta->findInt32(kKeyWidth, &width) 914 || !meta->findInt32(kKeyHeight, &height)) { 915 return BAD_VALUE; 916 } 917 918 msg->setInt32("width", width); 919 msg->setInt32("height", height); 920 921 int32_t displayWidth, displayHeight; 922 if (meta->findInt32(kKeyDisplayWidth, &displayWidth) 923 && meta->findInt32(kKeyDisplayHeight, &displayHeight)) { 924 msg->setInt32("display-width", displayWidth); 925 msg->setInt32("display-height", displayHeight); 926 } 927 928 int32_t sarWidth, sarHeight; 929 if (meta->findInt32(kKeySARWidth, &sarWidth) 930 && meta->findInt32(kKeySARHeight, &sarHeight)) { 931 msg->setInt32("sar-width", sarWidth); 932 msg->setInt32("sar-height", sarHeight); 933 } 934 935 if (!strncasecmp("image/", mime, 6)) { 936 int32_t tileWidth, tileHeight, gridRows, gridCols; 937 if (meta->findInt32(kKeyTileWidth, &tileWidth) 938 && meta->findInt32(kKeyTileHeight, &tileHeight) 939 && meta->findInt32(kKeyGridRows, &gridRows) 940 && meta->findInt32(kKeyGridCols, &gridCols)) { 941 msg->setInt32("tile-width", tileWidth); 942 msg->setInt32("tile-height", tileHeight); 943 msg->setInt32("grid-rows", gridRows); 944 msg->setInt32("grid-cols", gridCols); 945 } 946 int32_t isPrimary; 947 if (meta->findInt32(kKeyTrackIsDefault, &isPrimary) && isPrimary) { 948 msg->setInt32("is-default", 1); 949 } 950 } 951 952 int32_t colorFormat; 953 if (meta->findInt32(kKeyColorFormat, &colorFormat)) { 954 msg->setInt32("color-format", colorFormat); 955 } 956 957 int32_t cropLeft, cropTop, cropRight, cropBottom; 958 if (meta->findRect(kKeyCropRect, 959 &cropLeft, 960 &cropTop, 961 &cropRight, 962 &cropBottom)) { 963 msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom); 964 } 965 966 int32_t rotationDegrees; 967 if (meta->findInt32(kKeyRotation, &rotationDegrees)) { 968 msg->setInt32("rotation-degrees", rotationDegrees); 969 } 970 971 uint32_t type; 972 const void *data; 973 size_t size; 974 if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size) 975 && type == 'hdrS' && size == sizeof(HDRStaticInfo)) { 976 ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg); 977 } 978 979 if (meta->findData(kKeyHdr10PlusInfo, &type, &data, &size) 980 && size > 0) { 981 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 982 if (buffer.get() == NULL || buffer->base() == NULL) { 983 return NO_MEMORY; 984 } 985 memcpy(buffer->data(), data, size); 986 msg->setBuffer("hdr10-plus-info", buffer); 987 } 988 989 convertMetaDataToMessageColorAspects(meta, msg); 990 } else if (!strncasecmp("audio/", mime, 6)) { 991 int32_t numChannels, sampleRate; 992 if (!meta->findInt32(kKeyChannelCount, &numChannels) 993 || !meta->findInt32(kKeySampleRate, &sampleRate)) { 994 return BAD_VALUE; 995 } 996 997 msg->setInt32("channel-count", numChannels); 998 msg->setInt32("sample-rate", sampleRate); 999 1000 int32_t bitsPerSample; 1001 if (meta->findInt32(kKeyBitsPerSample, &bitsPerSample)) { 1002 msg->setInt32("bits-per-sample", bitsPerSample); 1003 } 1004 1005 int32_t channelMask; 1006 if (meta->findInt32(kKeyChannelMask, &channelMask)) { 1007 msg->setInt32("channel-mask", channelMask); 1008 } 1009 1010 int32_t delay = 0; 1011 if (meta->findInt32(kKeyEncoderDelay, &delay)) { 1012 msg->setInt32("encoder-delay", delay); 1013 } 1014 int32_t padding = 0; 1015 if (meta->findInt32(kKeyEncoderPadding, &padding)) { 1016 msg->setInt32("encoder-padding", padding); 1017 } 1018 1019 int32_t isADTS; 1020 if (meta->findInt32(kKeyIsADTS, &isADTS)) { 1021 msg->setInt32("is-adts", isADTS); 1022 } 1023 1024 int32_t aacProfile = -1; 1025 if (meta->findInt32(kKeyAACAOT, &aacProfile)) { 1026 msg->setInt32("aac-profile", aacProfile); 1027 } 1028 1029 int32_t pcmEncoding; 1030 if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) { 1031 msg->setInt32("pcm-encoding", pcmEncoding); 1032 } 1033 1034 int32_t hapticChannelCount; 1035 if (meta->findInt32(kKeyHapticChannelCount, &hapticChannelCount)) { 1036 msg->setInt32("haptic-channel-count", hapticChannelCount); 1037 } 1038 } 1039 1040 int32_t maxInputSize; 1041 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 1042 msg->setInt32("max-input-size", maxInputSize); 1043 } 1044 1045 int32_t maxWidth; 1046 if (meta->findInt32(kKeyMaxWidth, &maxWidth)) { 1047 msg->setInt32("max-width", maxWidth); 1048 } 1049 1050 int32_t maxHeight; 1051 if (meta->findInt32(kKeyMaxHeight, &maxHeight)) { 1052 msg->setInt32("max-height", maxHeight); 1053 } 1054 1055 int32_t rotationDegrees; 1056 if (meta->findInt32(kKeyRotation, &rotationDegrees)) { 1057 msg->setInt32("rotation-degrees", rotationDegrees); 1058 } 1059 1060 int32_t fps; 1061 if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) { 1062 msg->setInt32("frame-rate", fps); 1063 } 1064 1065 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1066 // Parse the AVCDecoderConfigurationRecord 1067 1068 const uint8_t *ptr = (const uint8_t *)data; 1069 1070 if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 1071 ALOGE("b/23680780"); 1072 return BAD_VALUE; 1073 } 1074 1075 parseAvcProfileLevelFromAvcc(ptr, size, msg); 1076 1077 // There is decodable content out there that fails the following 1078 // assertion, let's be lenient for now... 1079 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 1080 1081 size_t lengthSize __unused = 1 + (ptr[4] & 3); 1082 1083 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 1084 // violates it... 1085 // CHECK((ptr[5] >> 5) == 7); // reserved 1086 1087 size_t numSeqParameterSets = ptr[5] & 31; 1088 1089 ptr += 6; 1090 size -= 6; 1091 1092 sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024); 1093 if (buffer.get() == NULL || buffer->base() == NULL) { 1094 return NO_MEMORY; 1095 } 1096 buffer->setRange(0, 0); 1097 1098 for (size_t i = 0; i < numSeqParameterSets; ++i) { 1099 if (size < 2) { 1100 ALOGE("b/23680780"); 1101 return BAD_VALUE; 1102 } 1103 size_t length = U16_AT(ptr); 1104 1105 ptr += 2; 1106 size -= 2; 1107 1108 if (size < length) { 1109 return BAD_VALUE; 1110 } 1111 status_t err = copyNALUToABuffer(&buffer, ptr, length); 1112 if (err != OK) { 1113 return err; 1114 } 1115 1116 ptr += length; 1117 size -= length; 1118 } 1119 1120 buffer->meta()->setInt32("csd", true); 1121 buffer->meta()->setInt64("timeUs", 0); 1122 1123 msg->setBuffer("csd-0", buffer); 1124 1125 buffer = new (std::nothrow) ABuffer(1024); 1126 if (buffer.get() == NULL || buffer->base() == NULL) { 1127 return NO_MEMORY; 1128 } 1129 buffer->setRange(0, 0); 1130 1131 if (size < 1) { 1132 ALOGE("b/23680780"); 1133 return BAD_VALUE; 1134 } 1135 size_t numPictureParameterSets = *ptr; 1136 ++ptr; 1137 --size; 1138 1139 for (size_t i = 0; i < numPictureParameterSets; ++i) { 1140 if (size < 2) { 1141 ALOGE("b/23680780"); 1142 return BAD_VALUE; 1143 } 1144 size_t length = U16_AT(ptr); 1145 1146 ptr += 2; 1147 size -= 2; 1148 1149 if (size < length) { 1150 return BAD_VALUE; 1151 } 1152 status_t err = copyNALUToABuffer(&buffer, ptr, length); 1153 if (err != OK) { 1154 return err; 1155 } 1156 1157 ptr += length; 1158 size -= length; 1159 } 1160 1161 buffer->meta()->setInt32("csd", true); 1162 buffer->meta()->setInt64("timeUs", 0); 1163 msg->setBuffer("csd-1", buffer); 1164 } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { 1165 const uint8_t *ptr = (const uint8_t *)data; 1166 1167 if (size < 23 || (ptr[0] != 1 && ptr[0] != 0)) { 1168 // configurationVersion == 1 or 0 1169 // 1 is what the standard dictates, but some old muxers may have used 0. 1170 ALOGE("b/23680780"); 1171 return BAD_VALUE; 1172 } 1173 1174 const size_t dataSize = size; // save for later 1175 ptr += 22; 1176 size -= 22; 1177 1178 size_t numofArrays = (char)ptr[0]; 1179 ptr += 1; 1180 size -= 1; 1181 size_t j = 0, i = 0; 1182 1183 sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024); 1184 if (buffer.get() == NULL || buffer->base() == NULL) { 1185 return NO_MEMORY; 1186 } 1187 buffer->setRange(0, 0); 1188 1189 HevcParameterSets hvcc; 1190 1191 for (i = 0; i < numofArrays; i++) { 1192 if (size < 3) { 1193 ALOGE("b/23680780"); 1194 return BAD_VALUE; 1195 } 1196 ptr += 1; 1197 size -= 1; 1198 1199 //Num of nals 1200 size_t numofNals = U16_AT(ptr); 1201 1202 ptr += 2; 1203 size -= 2; 1204 1205 for (j = 0; j < numofNals; j++) { 1206 if (size < 2) { 1207 ALOGE("b/23680780"); 1208 return BAD_VALUE; 1209 } 1210 size_t length = U16_AT(ptr); 1211 1212 ptr += 2; 1213 size -= 2; 1214 1215 if (size < length) { 1216 return BAD_VALUE; 1217 } 1218 status_t err = copyNALUToABuffer(&buffer, ptr, length); 1219 if (err != OK) { 1220 return err; 1221 } 1222 (void)hvcc.addNalUnit(ptr, length); 1223 1224 ptr += length; 1225 size -= length; 1226 } 1227 } 1228 buffer->meta()->setInt32("csd", true); 1229 buffer->meta()->setInt64("timeUs", 0); 1230 msg->setBuffer("csd-0", buffer); 1231 1232 // if we saw VUI color information we know whether this is HDR because VUI trumps other 1233 // format parameters for HEVC. 1234 HevcParameterSets::Info info = hvcc.getInfo(); 1235 if (info & hvcc.kInfoHasColorDescription) { 1236 msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0); 1237 } 1238 1239 uint32_t isoPrimaries, isoTransfer, isoMatrix, isoRange; 1240 if (hvcc.findParam32(kColourPrimaries, &isoPrimaries) 1241 && hvcc.findParam32(kTransferCharacteristics, &isoTransfer) 1242 && hvcc.findParam32(kMatrixCoeffs, &isoMatrix) 1243 && hvcc.findParam32(kVideoFullRangeFlag, &isoRange)) { 1244 ALOGV("found iso color aspects : primaris=%d, transfer=%d, matrix=%d, range=%d", 1245 isoPrimaries, isoTransfer, isoMatrix, isoRange); 1246 1247 ColorAspects aspects; 1248 ColorUtils::convertIsoColorAspectsToCodecAspects( 1249 isoPrimaries, isoTransfer, isoMatrix, isoRange, aspects); 1250 1251 if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) { 1252 int32_t primaries; 1253 if (meta->findInt32(kKeyColorPrimaries, &primaries)) { 1254 ALOGV("unspecified primaries found, replaced to %d", primaries); 1255 aspects.mPrimaries = static_cast<ColorAspects::Primaries>(primaries); 1256 } 1257 } 1258 if (aspects.mTransfer == ColorAspects::TransferUnspecified) { 1259 int32_t transferFunction; 1260 if (meta->findInt32(kKeyTransferFunction, &transferFunction)) { 1261 ALOGV("unspecified transfer found, replaced to %d", transferFunction); 1262 aspects.mTransfer = static_cast<ColorAspects::Transfer>(transferFunction); 1263 } 1264 } 1265 if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) { 1266 int32_t colorMatrix; 1267 if (meta->findInt32(kKeyColorMatrix, &colorMatrix)) { 1268 ALOGV("unspecified matrix found, replaced to %d", colorMatrix); 1269 aspects.mMatrixCoeffs = static_cast<ColorAspects::MatrixCoeffs>(colorMatrix); 1270 } 1271 } 1272 if (aspects.mRange == ColorAspects::RangeUnspecified) { 1273 int32_t range; 1274 if (meta->findInt32(kKeyColorRange, &range)) { 1275 ALOGV("unspecified range found, replaced to %d", range); 1276 aspects.mRange = static_cast<ColorAspects::Range>(range); 1277 } 1278 } 1279 1280 int32_t standard, transfer, range; 1281 if (ColorUtils::convertCodecColorAspectsToPlatformAspects( 1282 aspects, &range, &standard, &transfer) == OK) { 1283 msg->setInt32("color-standard", standard); 1284 msg->setInt32("color-transfer", transfer); 1285 msg->setInt32("color-range", range); 1286 } 1287 } 1288 1289 parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg); 1290 } else if (meta->findData(kKeyAV1C, &type, &data, &size)) { 1291 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 1292 if (buffer.get() == NULL || buffer->base() == NULL) { 1293 return NO_MEMORY; 1294 } 1295 memcpy(buffer->data(), data, size); 1296 1297 buffer->meta()->setInt32("csd", true); 1298 buffer->meta()->setInt64("timeUs", 0); 1299 msg->setBuffer("csd-0", buffer); 1300 parseAV1ProfileLevelFromCsd(buffer, msg); 1301 } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 1302 ESDS esds((const char *)data, size); 1303 if (esds.InitCheck() != (status_t)OK) { 1304 return BAD_VALUE; 1305 } 1306 1307 const void *codec_specific_data; 1308 size_t codec_specific_data_size; 1309 esds.getCodecSpecificInfo( 1310 &codec_specific_data, &codec_specific_data_size); 1311 1312 sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size); 1313 if (buffer.get() == NULL || buffer->base() == NULL) { 1314 return NO_MEMORY; 1315 } 1316 1317 memcpy(buffer->data(), codec_specific_data, 1318 codec_specific_data_size); 1319 1320 buffer->meta()->setInt32("csd", true); 1321 buffer->meta()->setInt64("timeUs", 0); 1322 msg->setBuffer("csd-0", buffer); 1323 1324 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) { 1325 parseMpeg4ProfileLevelFromCsd(buffer, msg); 1326 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) { 1327 parseMpeg2ProfileLevelFromEsds(esds, msg); 1328 if (meta->findData(kKeyStreamHeader, &type, &data, &size)) { 1329 parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg); 1330 } 1331 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1332 parseAacProfileFromCsd(buffer, msg); 1333 } 1334 1335 uint32_t maxBitrate, avgBitrate; 1336 if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) { 1337 if (!meta->hasData(kKeyBitRate) 1338 && avgBitrate > 0 && avgBitrate <= INT32_MAX) { 1339 msg->setInt32("bitrate", (int32_t)avgBitrate); 1340 } else { 1341 (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate); 1342 } 1343 if (!meta->hasData(kKeyMaxBitRate) 1344 && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) { 1345 msg->setInt32("max-bitrate", (int32_t)maxBitrate); 1346 } 1347 } 1348 } else if (meta->findData(kKeyD263, &type, &data, &size)) { 1349 const uint8_t *ptr = (const uint8_t *)data; 1350 parseH263ProfileLevelFromD263(ptr, size, msg); 1351 } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) { 1352 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 1353 if (buffer.get() == NULL || buffer->base() == NULL) { 1354 return NO_MEMORY; 1355 } 1356 memcpy(buffer->data(), data, size); 1357 1358 buffer->meta()->setInt32("csd", true); 1359 buffer->meta()->setInt64("timeUs", 0); 1360 msg->setBuffer("csd-0", buffer); 1361 1362 if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) { 1363 return -EINVAL; 1364 } 1365 1366 buffer = new (std::nothrow) ABuffer(size); 1367 if (buffer.get() == NULL || buffer->base() == NULL) { 1368 return NO_MEMORY; 1369 } 1370 memcpy(buffer->data(), data, size); 1371 1372 buffer->meta()->setInt32("csd", true); 1373 buffer->meta()->setInt64("timeUs", 0); 1374 msg->setBuffer("csd-1", buffer); 1375 1376 if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) { 1377 return -EINVAL; 1378 } 1379 1380 buffer = new (std::nothrow) ABuffer(size); 1381 if (buffer.get() == NULL || buffer->base() == NULL) { 1382 return NO_MEMORY; 1383 } 1384 memcpy(buffer->data(), data, size); 1385 1386 buffer->meta()->setInt32("csd", true); 1387 buffer->meta()->setInt64("timeUs", 0); 1388 msg->setBuffer("csd-2", buffer); 1389 } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) { 1390 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 1391 if (buffer.get() == NULL || buffer->base() == NULL) { 1392 return NO_MEMORY; 1393 } 1394 memcpy(buffer->data(), data, size); 1395 1396 buffer->meta()->setInt32("csd", true); 1397 buffer->meta()->setInt64("timeUs", 0); 1398 msg->setBuffer("csd-0", buffer); 1399 1400 parseVp9ProfileLevelFromCsd(buffer, msg); 1401 } else if (meta->findData(kKeyAlacMagicCookie, &type, &data, &size)) { 1402 ALOGV("convertMetaDataToMessage found kKeyAlacMagicCookie of size %zu\n", size); 1403 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 1404 if (buffer.get() == NULL || buffer->base() == NULL) { 1405 return NO_MEMORY; 1406 } 1407 memcpy(buffer->data(), data, size); 1408 1409 buffer->meta()->setInt32("csd", true); 1410 buffer->meta()->setInt64("timeUs", 0); 1411 msg->setBuffer("csd-0", buffer); 1412 } 1413 1414 *format = msg; 1415 1416 return OK; 1417 } 1418 1419 const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) { 1420 uint8_t *res = NULL; 1421 if (length > 4) { 1422 // minus 1 as to not match NAL start code at end 1423 res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4); 1424 } 1425 return res != NULL && res < data + length - 4 ? res : &data[length]; 1426 } 1427 1428 static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> &csd1, char *avcc) { 1429 avcc[0] = 1; // version 1430 avcc[1] = 0x64; // profile (default to high) 1431 avcc[2] = 0; // constraints (default to none) 1432 avcc[3] = 0xd; // level (default to 1.3) 1433 avcc[4] = 0xff; // reserved+size 1434 1435 size_t i = 0; 1436 int numparams = 0; 1437 int lastparamoffset = 0; 1438 int avccidx = 6; 1439 do { 1440 i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data(); 1441 ALOGV("block at %zu, last was %d", i, lastparamoffset); 1442 if (lastparamoffset > 0) { 1443 const uint8_t *lastparam = csd0->data() + lastparamoffset; 1444 int size = i - lastparamoffset; 1445 if (size > 3) { 1446 if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) { 1447 ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x", 1448 avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]); 1449 } else if (!numparams) { 1450 // fill in profile, constraints and level 1451 memcpy(avcc + 1, lastparam + 1, 3); 1452 } 1453 } 1454 avcc[avccidx++] = size >> 8; 1455 avcc[avccidx++] = size & 0xff; 1456 memcpy(avcc+avccidx, lastparam, size); 1457 avccidx += size; 1458 numparams++; 1459 } 1460 i += 4; 1461 lastparamoffset = i; 1462 } while(i < csd0->size()); 1463 ALOGV("csd0 contains %d params", numparams); 1464 1465 avcc[5] = 0xe0 | numparams; 1466 //and now csd-1 1467 i = 0; 1468 numparams = 0; 1469 lastparamoffset = 0; 1470 int numpicparamsoffset = avccidx; 1471 avccidx++; 1472 do { 1473 i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data(); 1474 ALOGV("block at %zu, last was %d", i, lastparamoffset); 1475 if (lastparamoffset > 0) { 1476 int size = i - lastparamoffset; 1477 avcc[avccidx++] = size >> 8; 1478 avcc[avccidx++] = size & 0xff; 1479 memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 1480 avccidx += size; 1481 numparams++; 1482 } 1483 i += 4; 1484 lastparamoffset = i; 1485 } while(i < csd1->size()); 1486 avcc[numpicparamsoffset] = numparams; 1487 return avccidx; 1488 } 1489 1490 static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 1491 int csd0size = csd0->size(); 1492 esds[0] = 3; // kTag_ESDescriptor; 1493 int esdescriptorsize = 26 + csd0size; 1494 CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 1495 esds[1] = 0x80 | (esdescriptorsize >> 21); 1496 esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 1497 esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 1498 esds[4] = (esdescriptorsize & 0x7f); 1499 esds[5] = esds[6] = 0; // es id 1500 esds[7] = 0; // flags 1501 esds[8] = 4; // kTag_DecoderConfigDescriptor 1502 int configdescriptorsize = 18 + csd0size; 1503 esds[9] = 0x80 | (configdescriptorsize >> 21); 1504 esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 1505 esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 1506 esds[12] = (configdescriptorsize & 0x7f); 1507 esds[13] = 0x40; // objectTypeIndication 1508 // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers. 1509 esds[14] = 0x15; // streamType(5), upStream(0), 1510 esds[15] = 0x00; // 15-17: bufferSizeDB (6KB) 1511 esds[16] = 0x18; 1512 esds[17] = 0x00; 1513 esds[18] = 0x00; // 18-21: maxBitrate (64kbps) 1514 esds[19] = 0x00; 1515 esds[20] = 0xfa; 1516 esds[21] = 0x00; 1517 esds[22] = 0x00; // 22-25: avgBitrate (64kbps) 1518 esds[23] = 0x00; 1519 esds[24] = 0xfa; 1520 esds[25] = 0x00; 1521 esds[26] = 5; // kTag_DecoderSpecificInfo; 1522 esds[27] = 0x80 | (csd0size >> 21); 1523 esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 1524 esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 1525 esds[30] = (csd0size & 0x7f); 1526 memcpy((void*)&esds[31], csd0->data(), csd0size); 1527 // data following this is ignored, so don't bother appending it 1528 } 1529 1530 static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) { 1531 HevcParameterSets paramSets; 1532 uint8_t* data = csd0->data(); 1533 if (csd0->size() < 4) { 1534 ALOGE("csd0 too small"); 1535 return 0; 1536 } 1537 if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) { 1538 ALOGE("csd0 doesn't start with a start code"); 1539 return 0; 1540 } 1541 size_t prevNalOffset = 4; 1542 status_t err = OK; 1543 for (size_t i = 1; i < csd0->size() - 4; ++i) { 1544 if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) { 1545 continue; 1546 } 1547 err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset); 1548 if (err != OK) { 1549 return 0; 1550 } 1551 prevNalOffset = i + 4; 1552 } 1553 err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset); 1554 if (err != OK) { 1555 return 0; 1556 } 1557 size_t size = hvccSize; 1558 err = paramSets.makeHvcc(hvcc, &size, nalSizeLength); 1559 if (err != OK) { 1560 return 0; 1561 } 1562 return size; 1563 } 1564 1565 #if 0 1566 static void convertMessageToMetaDataInt32( 1567 const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) { 1568 int32_t value; 1569 if (msg->findInt32(name, &value)) { 1570 meta->setInt32(key, value); 1571 } 1572 } 1573 #endif 1574 1575 static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) { 1576 // 0 values are unspecified 1577 int32_t range = 0, standard = 0, transfer = 0; 1578 (void)msg->findInt32("color-range", &range); 1579 (void)msg->findInt32("color-standard", &standard); 1580 (void)msg->findInt32("color-transfer", &transfer); 1581 1582 ColorAspects colorAspects; 1583 memset(&colorAspects, 0, sizeof(colorAspects)); 1584 if (CodecBase::convertPlatformColorAspectsToCodecAspects( 1585 range, standard, transfer, colorAspects) != OK) { 1586 return; 1587 } 1588 1589 // save specified values to meta 1590 if (colorAspects.mRange != 0) { 1591 meta->setInt32(kKeyColorRange, colorAspects.mRange); 1592 } 1593 if (colorAspects.mPrimaries != 0) { 1594 meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries); 1595 } 1596 if (colorAspects.mTransfer != 0) { 1597 meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer); 1598 } 1599 if (colorAspects.mMatrixCoeffs != 0) { 1600 meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs); 1601 } 1602 } 1603 1604 void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 1605 AString mime; 1606 if (msg->findString("mime", &mime)) { 1607 meta->setCString(kKeyMIMEType, mime.c_str()); 1608 } else { 1609 ALOGW("did not find mime type"); 1610 } 1611 1612 convertMessageToMetaDataFromMappings(msg, meta); 1613 1614 int32_t systemId; 1615 if (msg->findInt32("ca-system-id", &systemId)) { 1616 meta->setInt32(kKeyCASystemID, systemId); 1617 1618 sp<ABuffer> caSessionId, caPvtData; 1619 if (msg->findBuffer("ca-session-id", &caSessionId)) { 1620 meta->setData(kKeyCASessionID, 0, caSessionId->data(), caSessionId->size()); 1621 } 1622 if (msg->findBuffer("ca-private-data", &caPvtData)) { 1623 meta->setData(kKeyCAPrivateData, 0, caPvtData->data(), caPvtData->size()); 1624 } 1625 } 1626 1627 int64_t durationUs; 1628 if (msg->findInt64("durationUs", &durationUs)) { 1629 meta->setInt64(kKeyDuration, durationUs); 1630 } 1631 1632 int32_t isSync; 1633 if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) { 1634 meta->setInt32(kKeyIsSyncFrame, 1); 1635 } 1636 1637 int32_t avgBitrate = 0; 1638 int32_t maxBitrate; 1639 if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) { 1640 meta->setInt32(kKeyBitRate, avgBitrate); 1641 } 1642 if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) { 1643 meta->setInt32(kKeyMaxBitRate, maxBitrate); 1644 } 1645 1646 AString lang; 1647 if (msg->findString("language", &lang)) { 1648 meta->setCString(kKeyMediaLanguage, lang.c_str()); 1649 } 1650 1651 if (mime.startsWith("video/") || mime.startsWith("image/")) { 1652 int32_t width; 1653 int32_t height; 1654 if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 1655 meta->setInt32(kKeyWidth, width); 1656 meta->setInt32(kKeyHeight, height); 1657 } else { 1658 ALOGV("did not find width and/or height"); 1659 } 1660 1661 int32_t sarWidth, sarHeight; 1662 if (msg->findInt32("sar-width", &sarWidth) 1663 && msg->findInt32("sar-height", &sarHeight)) { 1664 meta->setInt32(kKeySARWidth, sarWidth); 1665 meta->setInt32(kKeySARHeight, sarHeight); 1666 } 1667 1668 int32_t displayWidth, displayHeight; 1669 if (msg->findInt32("display-width", &displayWidth) 1670 && msg->findInt32("display-height", &displayHeight)) { 1671 meta->setInt32(kKeyDisplayWidth, displayWidth); 1672 meta->setInt32(kKeyDisplayHeight, displayHeight); 1673 } 1674 1675 if (mime.startsWith("image/")){ 1676 int32_t isPrimary; 1677 if (msg->findInt32("is-default", &isPrimary) && isPrimary) { 1678 meta->setInt32(kKeyTrackIsDefault, 1); 1679 } 1680 int32_t tileWidth, tileHeight, gridRows, gridCols; 1681 if (msg->findInt32("tile-width", &tileWidth)) { 1682 meta->setInt32(kKeyTileWidth, tileWidth); 1683 } 1684 if (msg->findInt32("tile-height", &tileHeight)) { 1685 meta->setInt32(kKeyTileHeight, tileHeight); 1686 } 1687 if (msg->findInt32("grid-rows", &gridRows)) { 1688 meta->setInt32(kKeyGridRows, gridRows); 1689 } 1690 if (msg->findInt32("grid-cols", &gridCols)) { 1691 meta->setInt32(kKeyGridCols, gridCols); 1692 } 1693 } 1694 1695 int32_t colorFormat; 1696 if (msg->findInt32("color-format", &colorFormat)) { 1697 meta->setInt32(kKeyColorFormat, colorFormat); 1698 } 1699 1700 int32_t cropLeft, cropTop, cropRight, cropBottom; 1701 if (msg->findRect("crop", 1702 &cropLeft, 1703 &cropTop, 1704 &cropRight, 1705 &cropBottom)) { 1706 meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom); 1707 } 1708 1709 int32_t rotationDegrees; 1710 if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 1711 meta->setInt32(kKeyRotation, rotationDegrees); 1712 } 1713 1714 if (msg->contains("hdr-static-info")) { 1715 HDRStaticInfo info; 1716 if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) { 1717 meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); 1718 } 1719 } 1720 1721 sp<ABuffer> hdr10PlusInfo; 1722 if (msg->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) { 1723 meta->setData(kKeyHdr10PlusInfo, 0, 1724 hdr10PlusInfo->data(), hdr10PlusInfo->size()); 1725 } 1726 1727 convertMessageToMetaDataColorAspects(msg, meta); 1728 1729 AString tsSchema; 1730 if (msg->findString("ts-schema", &tsSchema)) { 1731 unsigned int numLayers = 0; 1732 unsigned int numBLayers = 0; 1733 char dummy; 1734 int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c", 1735 &numLayers, &dummy, &numBLayers, &dummy); 1736 if ((tags == 1 || (tags == 3 && dummy == '+')) 1737 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers 1738 && numLayers + numBLayers <= INT32_MAX) { 1739 meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers); 1740 } 1741 } 1742 } else if (mime.startsWith("audio/")) { 1743 int32_t numChannels; 1744 if (msg->findInt32("channel-count", &numChannels)) { 1745 meta->setInt32(kKeyChannelCount, numChannels); 1746 } 1747 int32_t sampleRate; 1748 if (msg->findInt32("sample-rate", &sampleRate)) { 1749 meta->setInt32(kKeySampleRate, sampleRate); 1750 } 1751 int32_t bitsPerSample; 1752 if (msg->findInt32("bits-per-sample", &bitsPerSample)) { 1753 meta->setInt32(kKeyBitsPerSample, bitsPerSample); 1754 } 1755 int32_t channelMask; 1756 if (msg->findInt32("channel-mask", &channelMask)) { 1757 meta->setInt32(kKeyChannelMask, channelMask); 1758 } 1759 int32_t delay = 0; 1760 if (msg->findInt32("encoder-delay", &delay)) { 1761 meta->setInt32(kKeyEncoderDelay, delay); 1762 } 1763 int32_t padding = 0; 1764 if (msg->findInt32("encoder-padding", &padding)) { 1765 meta->setInt32(kKeyEncoderPadding, padding); 1766 } 1767 1768 int32_t isADTS; 1769 if (msg->findInt32("is-adts", &isADTS)) { 1770 meta->setInt32(kKeyIsADTS, isADTS); 1771 } 1772 1773 int32_t aacProfile = -1; 1774 if (msg->findInt32("aac-profile", &aacProfile)) { 1775 meta->setInt32(kKeyAACAOT, aacProfile); 1776 } 1777 1778 int32_t pcmEncoding; 1779 if (msg->findInt32("pcm-encoding", &pcmEncoding)) { 1780 meta->setInt32(kKeyPcmEncoding, pcmEncoding); 1781 } 1782 1783 int32_t hapticChannelCount; 1784 if (msg->findInt32("haptic-channel-count", &hapticChannelCount)) { 1785 meta->setInt32(kKeyHapticChannelCount, hapticChannelCount); 1786 } 1787 } 1788 1789 int32_t maxInputSize; 1790 if (msg->findInt32("max-input-size", &maxInputSize)) { 1791 meta->setInt32(kKeyMaxInputSize, maxInputSize); 1792 } 1793 1794 int32_t maxWidth; 1795 if (msg->findInt32("max-width", &maxWidth)) { 1796 meta->setInt32(kKeyMaxWidth, maxWidth); 1797 } 1798 1799 int32_t maxHeight; 1800 if (msg->findInt32("max-height", &maxHeight)) { 1801 meta->setInt32(kKeyMaxHeight, maxHeight); 1802 } 1803 1804 int32_t fps; 1805 float fpsFloat; 1806 if (msg->findInt32("frame-rate", &fps) && fps > 0) { 1807 meta->setInt32(kKeyFrameRate, fps); 1808 } else if (msg->findFloat("frame-rate", &fpsFloat) 1809 && fpsFloat >= 1 && fpsFloat <= INT32_MAX) { 1810 // truncate values to distinguish between e.g. 24 vs 23.976 fps 1811 meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat); 1812 } 1813 1814 // reassemble the csd data into its original form 1815 sp<ABuffer> csd0, csd1, csd2; 1816 if (msg->findBuffer("csd-0", &csd0)) { 1817 int csd0size = csd0->size(); 1818 if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { 1819 sp<ABuffer> csd1; 1820 if (msg->findBuffer("csd-1", &csd1)) { 1821 std::vector<char> avcc(csd0size + csd1->size() + 1024); 1822 size_t outsize = reassembleAVCC(csd0, csd1, avcc.data()); 1823 meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize); 1824 } 1825 } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || 1826 mime == MEDIA_MIMETYPE_VIDEO_MPEG4 || 1827 mime == MEDIA_MIMETYPE_AUDIO_WMA || 1828 mime == MEDIA_MIMETYPE_AUDIO_MS_ADPCM || 1829 mime == MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) { 1830 std::vector<char> esds(csd0size + 31); 1831 // The written ESDS is actually for an audio stream, but it's enough 1832 // for transporting the CSD to muxers. 1833 reassembleESDS(csd0, esds.data()); 1834 meta->setData(kKeyESDS, kTypeESDS, esds.data(), esds.size()); 1835 } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC || 1836 mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) { 1837 std::vector<uint8_t> hvcc(csd0size + 1024); 1838 size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4); 1839 meta->setData(kKeyHVCC, kTypeHVCC, hvcc.data(), outsize); 1840 } else if (mime == MEDIA_MIMETYPE_VIDEO_AV1) { 1841 meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size()); 1842 } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) { 1843 meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size()); 1844 } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) { 1845 size_t opusHeadSize = csd0->size(); 1846 size_t codecDelayBufSize = 0; 1847 size_t seekPreRollBufSize = 0; 1848 void *opusHeadBuf = csd0->data(); 1849 void *codecDelayBuf = NULL; 1850 void *seekPreRollBuf = NULL; 1851 if (msg->findBuffer("csd-1", &csd1)) { 1852 codecDelayBufSize = csd1->size(); 1853 codecDelayBuf = csd1->data(); 1854 } 1855 if (msg->findBuffer("csd-2", &csd2)) { 1856 seekPreRollBufSize = csd2->size(); 1857 seekPreRollBuf = csd2->data(); 1858 } 1859 /* Extract codec delay and seek pre roll from csd-0, 1860 * if csd-1 and csd-2 are not present */ 1861 if (!codecDelayBuf && !seekPreRollBuf) { 1862 GetOpusHeaderBuffers(csd0->data(), csd0->size(), &opusHeadBuf, 1863 &opusHeadSize, &codecDelayBuf, 1864 &codecDelayBufSize, &seekPreRollBuf, 1865 &seekPreRollBufSize); 1866 } 1867 meta->setData(kKeyOpusHeader, 0, opusHeadBuf, opusHeadSize); 1868 if (codecDelayBuf) { 1869 meta->setData(kKeyOpusCodecDelay, 0, codecDelayBuf, codecDelayBufSize); 1870 } 1871 if (seekPreRollBuf) { 1872 meta->setData(kKeyOpusSeekPreRoll, 0, seekPreRollBuf, seekPreRollBufSize); 1873 } 1874 } else if (mime == MEDIA_MIMETYPE_AUDIO_ALAC) { 1875 meta->setData(kKeyAlacMagicCookie, 0, csd0->data(), csd0->size()); 1876 } 1877 } else if (mime == MEDIA_MIMETYPE_VIDEO_AVC && msg->findBuffer("csd-avc", &csd0)) { 1878 meta->setData(kKeyAVCC, kTypeAVCC, csd0->data(), csd0->size()); 1879 } else if ((mime == MEDIA_MIMETYPE_VIDEO_HEVC || mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) 1880 && msg->findBuffer("csd-hevc", &csd0)) { 1881 meta->setData(kKeyHVCC, kTypeHVCC, csd0->data(), csd0->size()); 1882 } else if (msg->findBuffer("esds", &csd0)) { 1883 meta->setData(kKeyESDS, kTypeESDS, csd0->data(), csd0->size()); 1884 } else if (msg->findBuffer("mpeg2-stream-header", &csd0)) { 1885 meta->setData(kKeyStreamHeader, 'mdat', csd0->data(), csd0->size()); 1886 } else if (msg->findBuffer("d263", &csd0)) { 1887 meta->setData(kKeyD263, kTypeD263, csd0->data(), csd0->size()); 1888 } 1889 1890 // XXX TODO add whatever other keys there are 1891 1892 #if 0 1893 ALOGI("converted %s to:", msg->debugString(0).c_str()); 1894 meta->dumpToLog(); 1895 #endif 1896 } 1897 1898 AString MakeUserAgent() { 1899 AString ua; 1900 ua.append("stagefright/1.2 (Linux;Android "); 1901 1902 #if (PROPERTY_VALUE_MAX < 8) 1903 #error "PROPERTY_VALUE_MAX must be at least 8" 1904 #endif 1905 1906 char value[PROPERTY_VALUE_MAX]; 1907 property_get("ro.build.version.release", value, "Unknown"); 1908 ua.append(value); 1909 ua.append(")"); 1910 1911 return ua; 1912 } 1913 1914 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, 1915 const sp<MetaData>& meta) 1916 { 1917 int32_t sampleRate = 0; 1918 int32_t bitRate = 0; 1919 int32_t channelMask = 0; 1920 int32_t delaySamples = 0; 1921 int32_t paddingSamples = 0; 1922 1923 AudioParameter param = AudioParameter(); 1924 1925 if (meta->findInt32(kKeySampleRate, &sampleRate)) { 1926 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate); 1927 } 1928 if (meta->findInt32(kKeyChannelMask, &channelMask)) { 1929 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask); 1930 } 1931 if (meta->findInt32(kKeyBitRate, &bitRate)) { 1932 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate); 1933 } 1934 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) { 1935 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples); 1936 } 1937 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) { 1938 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples); 1939 } 1940 1941 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d," 1942 "delaySample %d, paddingSample %d", bitRate, sampleRate, 1943 channelMask, delaySamples, paddingSamples); 1944 1945 sink->setParameters(param.toString()); 1946 return OK; 1947 } 1948 1949 struct mime_conv_t { 1950 const char* mime; 1951 audio_format_t format; 1952 }; 1953 1954 static const struct mime_conv_t mimeLookup[] = { 1955 { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 }, 1956 { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT }, 1957 { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB }, 1958 { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB }, 1959 { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC }, 1960 { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS }, 1961 { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS}, 1962 { MEDIA_MIMETYPE_AUDIO_AC3, AUDIO_FORMAT_AC3}, 1963 { MEDIA_MIMETYPE_AUDIO_EAC3, AUDIO_FORMAT_E_AC3}, 1964 { MEDIA_MIMETYPE_AUDIO_EAC3_JOC, AUDIO_FORMAT_E_AC3_JOC}, 1965 { MEDIA_MIMETYPE_AUDIO_AC4, AUDIO_FORMAT_AC4}, 1966 { MEDIA_MIMETYPE_AUDIO_FLAC, AUDIO_FORMAT_FLAC}, 1967 { MEDIA_MIMETYPE_AUDIO_ALAC, AUDIO_FORMAT_ALAC }, 1968 { 0, AUDIO_FORMAT_INVALID } 1969 }; 1970 1971 status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime ) 1972 { 1973 const struct mime_conv_t* p = &mimeLookup[0]; 1974 while (p->mime != NULL) { 1975 if (0 == strcasecmp(mime, p->mime)) { 1976 format = p->format; 1977 return OK; 1978 } 1979 ++p; 1980 } 1981 1982 return BAD_VALUE; 1983 } 1984 1985 struct aac_format_conv_t { 1986 OMX_AUDIO_AACPROFILETYPE eAacProfileType; 1987 audio_format_t format; 1988 }; 1989 1990 static const struct aac_format_conv_t profileLookup[] = { 1991 { OMX_AUDIO_AACObjectMain, AUDIO_FORMAT_AAC_MAIN}, 1992 { OMX_AUDIO_AACObjectLC, AUDIO_FORMAT_AAC_LC}, 1993 { OMX_AUDIO_AACObjectSSR, AUDIO_FORMAT_AAC_SSR}, 1994 { OMX_AUDIO_AACObjectLTP, AUDIO_FORMAT_AAC_LTP}, 1995 { OMX_AUDIO_AACObjectHE, AUDIO_FORMAT_AAC_HE_V1}, 1996 { OMX_AUDIO_AACObjectScalable, AUDIO_FORMAT_AAC_SCALABLE}, 1997 { OMX_AUDIO_AACObjectERLC, AUDIO_FORMAT_AAC_ERLC}, 1998 { OMX_AUDIO_AACObjectLD, AUDIO_FORMAT_AAC_LD}, 1999 { OMX_AUDIO_AACObjectHE_PS, AUDIO_FORMAT_AAC_HE_V2}, 2000 { OMX_AUDIO_AACObjectELD, AUDIO_FORMAT_AAC_ELD}, 2001 { OMX_AUDIO_AACObjectXHE, AUDIO_FORMAT_AAC_XHE}, 2002 { OMX_AUDIO_AACObjectNull, AUDIO_FORMAT_AAC}, 2003 }; 2004 2005 void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile) 2006 { 2007 const struct aac_format_conv_t* p = &profileLookup[0]; 2008 while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) { 2009 if (eAacProfile == p->eAacProfileType) { 2010 format = p->format; 2011 return; 2012 } 2013 ++p; 2014 } 2015 format = AUDIO_FORMAT_AAC; 2016 return; 2017 } 2018 2019 status_t getAudioOffloadInfo(const sp<MetaData>& meta, bool hasVideo, 2020 bool isStreaming, audio_stream_type_t streamType, audio_offload_info_t *info) 2021 { 2022 const char *mime; 2023 if (meta == NULL) { 2024 return BAD_VALUE; 2025 } 2026 CHECK(meta->findCString(kKeyMIMEType, &mime)); 2027 2028 (*info) = AUDIO_INFO_INITIALIZER; 2029 2030 info->format = AUDIO_FORMAT_INVALID; 2031 if (mapMimeToAudioFormat(info->format, mime) != OK) { 2032 ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime); 2033 return BAD_VALUE; 2034 } else { 2035 ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info->format); 2036 } 2037 2038 if (AUDIO_FORMAT_INVALID == info->format) { 2039 // can't offload if we don't know what the source format is 2040 ALOGE("mime type \"%s\" not a known audio format", mime); 2041 return BAD_VALUE; 2042 } 2043 2044 // Redefine aac format according to its profile 2045 // Offloading depends on audio DSP capabilities. 2046 int32_t aacaot = -1; 2047 if (meta->findInt32(kKeyAACAOT, &aacaot)) { 2048 mapAACProfileToAudioFormat(info->format,(OMX_AUDIO_AACPROFILETYPE) aacaot); 2049 } 2050 2051 int32_t srate = -1; 2052 if (!meta->findInt32(kKeySampleRate, &srate)) { 2053 ALOGV("track of type '%s' does not publish sample rate", mime); 2054 } 2055 info->sample_rate = srate; 2056 2057 int32_t cmask = 0; 2058 if (!meta->findInt32(kKeyChannelMask, &cmask) || cmask == CHANNEL_MASK_USE_CHANNEL_ORDER) { 2059 ALOGV("track of type '%s' does not publish channel mask", mime); 2060 2061 // Try a channel count instead 2062 int32_t channelCount; 2063 if (!meta->findInt32(kKeyChannelCount, &channelCount)) { 2064 ALOGV("track of type '%s' does not publish channel count", mime); 2065 } else { 2066 cmask = audio_channel_out_mask_from_count(channelCount); 2067 } 2068 } 2069 info->channel_mask = cmask; 2070 2071 int64_t duration = 0; 2072 if (!meta->findInt64(kKeyDuration, &duration)) { 2073 ALOGV("track of type '%s' does not publish duration", mime); 2074 } 2075 info->duration_us = duration; 2076 2077 int32_t brate = -1; 2078 if (!meta->findInt32(kKeyBitRate, &brate)) { 2079 ALOGV("track of type '%s' does not publish bitrate", mime); 2080 } 2081 info->bit_rate = brate; 2082 2083 2084 info->stream_type = streamType; 2085 info->has_video = hasVideo; 2086 info->is_streaming = isStreaming; 2087 return OK; 2088 } 2089 2090 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, 2091 bool isStreaming, audio_stream_type_t streamType) 2092 { 2093 audio_offload_info_t info = AUDIO_INFO_INITIALIZER; 2094 if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) { 2095 return false; 2096 } 2097 // Check if offload is possible for given format, stream type, sample rate, 2098 // bit rate, duration, video and streaming 2099 return AudioSystem::isOffloadSupported(info); 2100 } 2101 2102 AString uriDebugString(const AString &uri, bool incognito) { 2103 if (incognito) { 2104 return AString("<URI suppressed>"); 2105 } 2106 2107 if (property_get_bool("media.stagefright.log-uri", false)) { 2108 return uri; 2109 } 2110 2111 // find scheme 2112 AString scheme; 2113 const char *chars = uri.c_str(); 2114 for (size_t i = 0; i < uri.size(); i++) { 2115 const char c = chars[i]; 2116 if (!isascii(c)) { 2117 break; 2118 } else if (isalpha(c)) { 2119 continue; 2120 } else if (i == 0) { 2121 // first character must be a letter 2122 break; 2123 } else if (isdigit(c) || c == '+' || c == '.' || c =='-') { 2124 continue; 2125 } else if (c != ':') { 2126 break; 2127 } 2128 scheme = AString(uri, 0, i); 2129 scheme.append("://<suppressed>"); 2130 return scheme; 2131 } 2132 return AString("<no-scheme URI suppressed>"); 2133 } 2134 2135 HLSTime::HLSTime(const sp<AMessage>& meta) : 2136 mSeq(-1), 2137 mTimeUs(-1LL), 2138 mMeta(meta) { 2139 if (meta != NULL) { 2140 CHECK(meta->findInt32("discontinuitySeq", &mSeq)); 2141 CHECK(meta->findInt64("timeUs", &mTimeUs)); 2142 } 2143 } 2144 2145 int64_t HLSTime::getSegmentTimeUs() const { 2146 int64_t segmentStartTimeUs = -1LL; 2147 if (mMeta != NULL) { 2148 CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs)); 2149 2150 int64_t segmentFirstTimeUs; 2151 if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) { 2152 segmentStartTimeUs += mTimeUs - segmentFirstTimeUs; 2153 } 2154 2155 // adjust segment time by playlist age (for live streaming) 2156 int64_t playlistTimeUs; 2157 if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) { 2158 int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs; 2159 2160 int64_t durationUs; 2161 CHECK(mMeta->findInt64("segmentDurationUs", &durationUs)); 2162 2163 // round to nearest whole segment 2164 playlistAgeUs = (playlistAgeUs + durationUs / 2) 2165 / durationUs * durationUs; 2166 2167 segmentStartTimeUs -= playlistAgeUs; 2168 if (segmentStartTimeUs < 0) { 2169 segmentStartTimeUs = 0; 2170 } 2171 } 2172 } 2173 return segmentStartTimeUs; 2174 } 2175 2176 bool operator <(const HLSTime &t0, const HLSTime &t1) { 2177 // we can only compare discontinuity sequence and timestamp. 2178 // (mSegmentTimeUs is not reliable in live streaming case, it's the 2179 // time starting from beginning of playlist but playlist could change.) 2180 return t0.mSeq < t1.mSeq 2181 || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs); 2182 } 2183 2184 void writeToAMessage(const sp<AMessage> &msg, const AudioPlaybackRate &rate) { 2185 msg->setFloat("speed", rate.mSpeed); 2186 msg->setFloat("pitch", rate.mPitch); 2187 msg->setInt32("audio-fallback-mode", rate.mFallbackMode); 2188 msg->setInt32("audio-stretch-mode", rate.mStretchMode); 2189 } 2190 2191 void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) { 2192 *rate = AUDIO_PLAYBACK_RATE_DEFAULT; 2193 CHECK(msg->findFloat("speed", &rate->mSpeed)); 2194 CHECK(msg->findFloat("pitch", &rate->mPitch)); 2195 CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode)); 2196 CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode)); 2197 } 2198 2199 void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float videoFpsHint) { 2200 msg->setInt32("sync-source", sync.mSource); 2201 msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode); 2202 msg->setFloat("tolerance", sync.mTolerance); 2203 msg->setFloat("video-fps", videoFpsHint); 2204 } 2205 2206 void readFromAMessage( 2207 const sp<AMessage> &msg, 2208 AVSyncSettings *sync /* nonnull */, 2209 float *videoFps /* nonnull */) { 2210 AVSyncSettings settings; 2211 CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource)); 2212 CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode)); 2213 CHECK(msg->findFloat("tolerance", &settings.mTolerance)); 2214 CHECK(msg->findFloat("video-fps", videoFps)); 2215 *sync = settings; 2216 } 2217 2218 void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering) { 2219 msg->setInt32("init-ms", buffering.mInitialMarkMs); 2220 msg->setInt32("resume-playback-ms", buffering.mResumePlaybackMarkMs); 2221 } 2222 2223 void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */) { 2224 int32_t value; 2225 if (msg->findInt32("init-ms", &value)) { 2226 buffering->mInitialMarkMs = value; 2227 } 2228 if (msg->findInt32("resume-playback-ms", &value)) { 2229 buffering->mResumePlaybackMarkMs = value; 2230 } 2231 } 2232 2233 AString nameForFd(int fd) { 2234 const size_t SIZE = 256; 2235 char buffer[SIZE]; 2236 AString result; 2237 snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd); 2238 struct stat s; 2239 if (lstat(buffer, &s) == 0) { 2240 if ((s.st_mode & S_IFMT) == S_IFLNK) { 2241 char linkto[256]; 2242 int len = readlink(buffer, linkto, sizeof(linkto)); 2243 if(len > 0) { 2244 if(len > 255) { 2245 linkto[252] = '.'; 2246 linkto[253] = '.'; 2247 linkto[254] = '.'; 2248 linkto[255] = 0; 2249 } else { 2250 linkto[len] = 0; 2251 } 2252 result.append(linkto); 2253 } 2254 } else { 2255 result.append("unexpected type for "); 2256 result.append(buffer); 2257 } 2258 } else { 2259 result.append("couldn't open "); 2260 result.append(buffer); 2261 } 2262 return result; 2263 } 2264 2265 } // namespace android 2266