1 /* 2 * Copyright (C) 2010 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 "MatroskaExtractor" 19 #include <utils/Log.h> 20 21 #include "FLACDecoder.h" 22 #include "MatroskaExtractor.h" 23 24 #include <media/DataSourceBase.h> 25 #include <media/ExtractorUtils.h> 26 #include <media/MediaTrack.h> 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/foundation/AUtils.h> 29 #include <media/stagefright/foundation/ABuffer.h> 30 #include <media/stagefright/foundation/ByteUtils.h> 31 #include <media/stagefright/foundation/ColorUtils.h> 32 #include <media/stagefright/foundation/hexdump.h> 33 #include <media/stagefright/MediaBufferBase.h> 34 #include <media/stagefright/MediaDefs.h> 35 #include <media/stagefright/MediaErrors.h> 36 #include <media/stagefright/MetaData.h> 37 #include <media/stagefright/MetaDataUtils.h> 38 #include <utils/String8.h> 39 40 #include <arpa/inet.h> 41 #include <inttypes.h> 42 #include <vector> 43 44 namespace android { 45 46 struct DataSourceBaseReader : public mkvparser::IMkvReader { 47 explicit DataSourceBaseReader(DataSourceBase *source) 48 : mSource(source) { 49 } 50 51 virtual int Read(long long position, long length, unsigned char* buffer) { 52 CHECK(position >= 0); 53 CHECK(length >= 0); 54 55 if (length == 0) { 56 return 0; 57 } 58 59 ssize_t n = mSource->readAt(position, buffer, length); 60 61 if (n <= 0) { 62 return -1; 63 } 64 65 return 0; 66 } 67 68 virtual int Length(long long* total, long long* available) { 69 off64_t size; 70 if (mSource->getSize(&size) != OK) { 71 *total = -1; 72 *available = (long long)((1ull << 63) - 1); 73 74 return 0; 75 } 76 77 if (total) { 78 *total = size; 79 } 80 81 if (available) { 82 *available = size; 83 } 84 85 return 0; 86 } 87 88 private: 89 DataSourceBase *mSource; 90 91 DataSourceBaseReader(const DataSourceBaseReader &); 92 DataSourceBaseReader &operator=(const DataSourceBaseReader &); 93 }; 94 95 //////////////////////////////////////////////////////////////////////////////// 96 97 struct BlockIterator { 98 BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index); 99 100 bool eos() const; 101 102 void advance(); 103 void reset(); 104 105 void seek( 106 int64_t seekTimeUs, bool isAudio, 107 int64_t *actualFrameTimeUs); 108 109 const mkvparser::Block *block() const; 110 int64_t blockTimeUs() const; 111 112 private: 113 MatroskaExtractor *mExtractor; 114 long long mTrackNum; 115 unsigned long mIndex; 116 117 const mkvparser::Cluster *mCluster; 118 const mkvparser::BlockEntry *mBlockEntry; 119 long mBlockEntryIndex; 120 121 void advance_l(); 122 123 BlockIterator(const BlockIterator &); 124 BlockIterator &operator=(const BlockIterator &); 125 }; 126 127 struct MatroskaSource : public MediaTrack { 128 MatroskaSource(MatroskaExtractor *extractor, size_t index); 129 130 virtual status_t start(MetaDataBase *params); 131 virtual status_t stop(); 132 133 virtual status_t getFormat(MetaDataBase &); 134 135 virtual status_t read( 136 MediaBufferBase **buffer, const ReadOptions *options); 137 138 protected: 139 virtual ~MatroskaSource(); 140 141 private: 142 enum Type { 143 AVC, 144 AAC, 145 HEVC, 146 OTHER 147 }; 148 149 MatroskaExtractor *mExtractor; 150 size_t mTrackIndex; 151 Type mType; 152 bool mIsAudio; 153 BlockIterator mBlockIter; 154 ssize_t mNALSizeLen; // for type AVC or HEVC 155 156 List<MediaBufferBase *> mPendingFrames; 157 158 status_t advance(); 159 160 status_t setWebmBlockCryptoInfo(MediaBufferBase *mbuf); 161 status_t readBlock(); 162 void clearPendingFrames(); 163 164 MatroskaSource(const MatroskaSource &); 165 MatroskaSource &operator=(const MatroskaSource &); 166 }; 167 168 const mkvparser::Track* MatroskaExtractor::TrackInfo::getTrack() const { 169 return mExtractor->mSegment->GetTracks()->GetTrackByNumber(mTrackNum); 170 } 171 172 // This function does exactly the same as mkvparser::Cues::Find, except that it 173 // searches in our own track based vectors. We should not need this once mkvparser 174 // adds the same functionality. 175 const mkvparser::CuePoint::TrackPosition *MatroskaExtractor::TrackInfo::find( 176 long long timeNs) const { 177 ALOGV("mCuePoints.size %zu", mCuePoints.size()); 178 if (mCuePoints.empty()) { 179 return NULL; 180 } 181 182 const mkvparser::CuePoint* cp = mCuePoints.itemAt(0); 183 const mkvparser::Track* track = getTrack(); 184 if (timeNs <= cp->GetTime(mExtractor->mSegment)) { 185 return cp->Find(track); 186 } 187 188 // Binary searches through relevant cues; assumes cues are ordered by timecode. 189 // If we do detect out-of-order cues, return NULL. 190 size_t lo = 0; 191 size_t hi = mCuePoints.size(); 192 while (lo < hi) { 193 const size_t mid = lo + (hi - lo) / 2; 194 const mkvparser::CuePoint* const midCp = mCuePoints.itemAt(mid); 195 const long long cueTimeNs = midCp->GetTime(mExtractor->mSegment); 196 if (cueTimeNs <= timeNs) { 197 lo = mid + 1; 198 } else { 199 hi = mid; 200 } 201 } 202 203 if (lo == 0) { 204 return NULL; 205 } 206 207 cp = mCuePoints.itemAt(lo - 1); 208 if (cp->GetTime(mExtractor->mSegment) > timeNs) { 209 return NULL; 210 } 211 212 return cp->Find(track); 213 } 214 215 MatroskaSource::MatroskaSource( 216 MatroskaExtractor *extractor, size_t index) 217 : mExtractor(extractor), 218 mTrackIndex(index), 219 mType(OTHER), 220 mIsAudio(false), 221 mBlockIter(mExtractor, 222 mExtractor->mTracks.itemAt(index).mTrackNum, 223 index), 224 mNALSizeLen(-1) { 225 MetaDataBase &meta = mExtractor->mTracks.editItemAt(index).mMeta; 226 227 const char *mime; 228 CHECK(meta.findCString(kKeyMIMEType, &mime)); 229 230 mIsAudio = !strncasecmp("audio/", mime, 6); 231 232 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 233 mType = AVC; 234 235 uint32_t dummy; 236 const uint8_t *avcc; 237 size_t avccSize; 238 int32_t nalSizeLen = 0; 239 if (meta.findInt32(kKeyNalLengthSize, &nalSizeLen)) { 240 if (nalSizeLen >= 0 && nalSizeLen <= 4) { 241 mNALSizeLen = nalSizeLen; 242 } 243 } else if (meta.findData(kKeyAVCC, &dummy, (const void **)&avcc, &avccSize) 244 && avccSize >= 5u) { 245 mNALSizeLen = 1 + (avcc[4] & 3); 246 ALOGV("mNALSizeLen = %zd", mNALSizeLen); 247 } else { 248 ALOGE("No mNALSizeLen"); 249 } 250 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 251 mType = HEVC; 252 253 uint32_t dummy; 254 const uint8_t *hvcc; 255 size_t hvccSize; 256 if (meta.findData(kKeyHVCC, &dummy, (const void **)&hvcc, &hvccSize) 257 && hvccSize >= 22u) { 258 mNALSizeLen = 1 + (hvcc[14+7] & 3); 259 ALOGV("mNALSizeLen = %zu", mNALSizeLen); 260 } else { 261 ALOGE("No mNALSizeLen"); 262 } 263 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 264 mType = AAC; 265 } 266 } 267 268 MatroskaSource::~MatroskaSource() { 269 clearPendingFrames(); 270 } 271 272 status_t MatroskaSource::start(MetaDataBase * /* params */) { 273 if (mType == AVC && mNALSizeLen < 0) { 274 return ERROR_MALFORMED; 275 } 276 277 mBlockIter.reset(); 278 279 return OK; 280 } 281 282 status_t MatroskaSource::stop() { 283 clearPendingFrames(); 284 285 return OK; 286 } 287 288 status_t MatroskaSource::getFormat(MetaDataBase &meta) { 289 meta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 290 return OK; 291 } 292 293 //////////////////////////////////////////////////////////////////////////////// 294 295 BlockIterator::BlockIterator( 296 MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index) 297 : mExtractor(extractor), 298 mTrackNum(trackNum), 299 mIndex(index), 300 mCluster(NULL), 301 mBlockEntry(NULL), 302 mBlockEntryIndex(0) { 303 reset(); 304 } 305 306 bool BlockIterator::eos() const { 307 return mCluster == NULL || mCluster->EOS(); 308 } 309 310 void BlockIterator::advance() { 311 Mutex::Autolock autoLock(mExtractor->mLock); 312 advance_l(); 313 } 314 315 void BlockIterator::advance_l() { 316 for (;;) { 317 long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); 318 ALOGV("GetEntry returned %ld", res); 319 320 long long pos; 321 long len; 322 if (res < 0) { 323 // Need to parse this cluster some more 324 325 CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); 326 327 res = mCluster->Parse(pos, len); 328 ALOGV("Parse returned %ld", res); 329 330 if (res < 0) { 331 // I/O error 332 333 ALOGE("Cluster::Parse returned result %ld", res); 334 335 mCluster = NULL; 336 break; 337 } 338 339 continue; 340 } else if (res == 0) { 341 // We're done with this cluster 342 343 const mkvparser::Cluster *nextCluster; 344 res = mExtractor->mSegment->ParseNext( 345 mCluster, nextCluster, pos, len); 346 ALOGV("ParseNext returned %ld", res); 347 348 if (res != 0) { 349 // EOF or error 350 351 mCluster = NULL; 352 break; 353 } 354 355 CHECK_EQ(res, 0); 356 CHECK(nextCluster != NULL); 357 CHECK(!nextCluster->EOS()); 358 359 mCluster = nextCluster; 360 361 res = mCluster->Parse(pos, len); 362 ALOGV("Parse (2) returned %ld", res); 363 364 if (res < 0) { 365 // I/O error 366 367 ALOGE("Cluster::Parse returned result %ld", res); 368 369 mCluster = NULL; 370 break; 371 } 372 373 mBlockEntryIndex = 0; 374 continue; 375 } 376 377 CHECK(mBlockEntry != NULL); 378 CHECK(mBlockEntry->GetBlock() != NULL); 379 ++mBlockEntryIndex; 380 381 if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 382 break; 383 } 384 } 385 } 386 387 void BlockIterator::reset() { 388 Mutex::Autolock autoLock(mExtractor->mLock); 389 390 mCluster = mExtractor->mSegment->GetFirst(); 391 mBlockEntry = NULL; 392 mBlockEntryIndex = 0; 393 394 do { 395 advance_l(); 396 } while (!eos() && block()->GetTrackNumber() != mTrackNum); 397 } 398 399 void BlockIterator::seek( 400 int64_t seekTimeUs, bool isAudio, 401 int64_t *actualFrameTimeUs) { 402 Mutex::Autolock autoLock(mExtractor->mLock); 403 404 *actualFrameTimeUs = -1ll; 405 406 if (seekTimeUs > INT64_MAX / 1000ll || 407 seekTimeUs < INT64_MIN / 1000ll || 408 (mExtractor->mSeekPreRollNs > 0 && 409 (seekTimeUs * 1000ll) < INT64_MIN + mExtractor->mSeekPreRollNs) || 410 (mExtractor->mSeekPreRollNs < 0 && 411 (seekTimeUs * 1000ll) > INT64_MAX + mExtractor->mSeekPreRollNs)) { 412 ALOGE("cannot seek to %lld", (long long) seekTimeUs); 413 return; 414 } 415 416 const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs; 417 418 mkvparser::Segment* const pSegment = mExtractor->mSegment; 419 420 // Special case the 0 seek to avoid loading Cues when the application 421 // extraneously seeks to 0 before playing. 422 if (seekTimeNs <= 0) { 423 ALOGV("Seek to beginning: %" PRId64, seekTimeUs); 424 mCluster = pSegment->GetFirst(); 425 mBlockEntryIndex = 0; 426 do { 427 advance_l(); 428 } while (!eos() && block()->GetTrackNumber() != mTrackNum); 429 return; 430 } 431 432 ALOGV("Seeking to: %" PRId64, seekTimeUs); 433 434 // If the Cues have not been located then find them. 435 const mkvparser::Cues* pCues = pSegment->GetCues(); 436 const mkvparser::SeekHead* pSH = pSegment->GetSeekHead(); 437 if (!pCues && pSH) { 438 const size_t count = pSH->GetCount(); 439 const mkvparser::SeekHead::Entry* pEntry; 440 ALOGV("No Cues yet"); 441 442 for (size_t index = 0; index < count; index++) { 443 pEntry = pSH->GetEntry(index); 444 445 if (pEntry->id == 0x0C53BB6B) { // Cues ID 446 long len; long long pos; 447 pSegment->ParseCues(pEntry->pos, pos, len); 448 pCues = pSegment->GetCues(); 449 ALOGV("Cues found"); 450 break; 451 } 452 } 453 454 if (!pCues) { 455 ALOGE("No Cues in file"); 456 return; 457 } 458 } 459 else if (!pSH) { 460 ALOGE("No SeekHead"); 461 return; 462 } 463 464 const mkvparser::CuePoint* pCP; 465 mkvparser::Tracks const *pTracks = pSegment->GetTracks(); 466 while (!pCues->DoneParsing()) { 467 pCues->LoadCuePoint(); 468 pCP = pCues->GetLast(); 469 CHECK(pCP); 470 471 size_t trackCount = mExtractor->mTracks.size(); 472 for (size_t index = 0; index < trackCount; ++index) { 473 MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index); 474 const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum); 475 if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK 476 track.mCuePoints.push_back(pCP); 477 } 478 } 479 480 if (pCP->GetTime(pSegment) >= seekTimeNs) { 481 ALOGV("Parsed past relevant Cue"); 482 break; 483 } 484 } 485 486 const mkvparser::CuePoint::TrackPosition *pTP = NULL; 487 const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum); 488 if (thisTrack->GetType() == 1) { // video 489 MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex); 490 pTP = track.find(seekTimeNs); 491 } else { 492 // The Cue index is built around video keyframes 493 unsigned long int trackCount = pTracks->GetTracksCount(); 494 for (size_t index = 0; index < trackCount; ++index) { 495 const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index); 496 if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) { 497 ALOGV("Video track located at %zu", index); 498 break; 499 } 500 } 501 } 502 503 504 // Always *search* based on the video track, but finalize based on mTrackNum 505 if (!pTP) { 506 ALOGE("Did not locate the video track for seeking"); 507 return; 508 } 509 510 mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos); 511 512 CHECK(mCluster); 513 CHECK(!mCluster->EOS()); 514 515 // mBlockEntryIndex starts at 0 but m_block starts at 1 516 CHECK_GT(pTP->m_block, 0); 517 mBlockEntryIndex = pTP->m_block - 1; 518 519 for (;;) { 520 advance_l(); 521 522 if (eos()) break; 523 524 if (isAudio || block()->IsKey()) { 525 // Accept the first key frame 526 int64_t frameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL; 527 if (thisTrack->GetType() == 1 || frameTimeUs >= seekTimeUs) { 528 *actualFrameTimeUs = frameTimeUs; 529 ALOGV("Requested seek point: %" PRId64 " actual: %" PRId64, 530 seekTimeUs, *actualFrameTimeUs); 531 break; 532 } 533 } 534 } 535 } 536 537 const mkvparser::Block *BlockIterator::block() const { 538 CHECK(!eos()); 539 540 return mBlockEntry->GetBlock(); 541 } 542 543 int64_t BlockIterator::blockTimeUs() const { 544 if (mCluster == NULL || mBlockEntry == NULL) { 545 return -1; 546 } 547 return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 548 } 549 550 //////////////////////////////////////////////////////////////////////////////// 551 552 static unsigned U24_AT(const uint8_t *ptr) { 553 return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 554 } 555 556 static AString uriDebugString(const char *uri) { 557 // find scheme 558 AString scheme; 559 for (size_t i = 0; i < strlen(uri); i++) { 560 const char c = uri[i]; 561 if (!isascii(c)) { 562 break; 563 } else if (isalpha(c)) { 564 continue; 565 } else if (i == 0) { 566 // first character must be a letter 567 break; 568 } else if (isdigit(c) || c == '+' || c == '.' || c =='-') { 569 continue; 570 } else if (c != ':') { 571 break; 572 } 573 scheme = AString(uri, 0, i); 574 scheme.append("://<suppressed>"); 575 return scheme; 576 } 577 return AString("<no-scheme URI suppressed>"); 578 } 579 580 void MatroskaSource::clearPendingFrames() { 581 while (!mPendingFrames.empty()) { 582 MediaBufferBase *frame = *mPendingFrames.begin(); 583 mPendingFrames.erase(mPendingFrames.begin()); 584 585 frame->release(); 586 frame = NULL; 587 } 588 } 589 590 status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) { 591 if (mbuf->range_length() < 1 || mbuf->range_length() - 1 > INT32_MAX) { 592 // 1-byte signal 593 return ERROR_MALFORMED; 594 } 595 596 const uint8_t *data = (const uint8_t *)mbuf->data() + mbuf->range_offset(); 597 bool encrypted = data[0] & 0x1; 598 bool partitioned = data[0] & 0x2; 599 if (encrypted && mbuf->range_length() < 9) { 600 // 1-byte signal + 8-byte IV 601 return ERROR_MALFORMED; 602 } 603 604 MetaDataBase &meta = mbuf->meta_data(); 605 if (encrypted) { 606 uint8_t ctrCounter[16] = { 0 }; 607 uint32_t type; 608 const uint8_t *keyId; 609 size_t keyIdSize; 610 const MetaDataBase &trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 611 CHECK(trackMeta.findData(kKeyCryptoKey, &type, (const void **)&keyId, &keyIdSize)); 612 meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize); 613 memcpy(ctrCounter, data + 1, 8); 614 meta.setData(kKeyCryptoIV, 0, ctrCounter, 16); 615 if (partitioned) { 616 /* 0 1 2 3 617 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 618 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 619 * | Signal Byte | | 620 * +-+-+-+-+-+-+-+-+ IV | 621 * | | 622 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 623 * | | num_partition | Partition 0 offset -> | 624 * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| 625 * | -> Partition 0 offset | ... | 626 * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| 627 * | ... | Partition n-1 offset -> | 628 * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| 629 * | -> Partition n-1 offset | | 630 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 631 * | Clear/encrypted sample data | 632 * | | 633 * | | 634 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 635 */ 636 if (mbuf->range_length() < 10) { 637 return ERROR_MALFORMED; 638 } 639 uint8_t numPartitions = data[9]; 640 if (mbuf->range_length() - 10 < numPartitions * sizeof(uint32_t)) { 641 return ERROR_MALFORMED; 642 } 643 std::vector<uint32_t> plainSizes, encryptedSizes; 644 uint32_t prev = 0; 645 uint32_t frameOffset = 10 + numPartitions * sizeof(uint32_t); 646 const uint32_t *partitions = reinterpret_cast<const uint32_t*>(data + 10); 647 for (uint32_t i = 0; i <= numPartitions; ++i) { 648 uint32_t p_i = i < numPartitions 649 ? ntohl(partitions[i]) 650 : (mbuf->range_length() - frameOffset); 651 if (p_i < prev) { 652 return ERROR_MALFORMED; 653 } 654 uint32_t size = p_i - prev; 655 prev = p_i; 656 if (i % 2) { 657 encryptedSizes.push_back(size); 658 } else { 659 plainSizes.push_back(size); 660 } 661 } 662 if (plainSizes.size() > encryptedSizes.size()) { 663 encryptedSizes.push_back(0); 664 } 665 uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size(); 666 uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size(); 667 meta.setData(kKeyPlainSizes, 0, plainSizes.data(), sizeofPlainSizes); 668 meta.setData(kKeyEncryptedSizes, 0, encryptedSizes.data(), sizeofEncryptedSizes); 669 mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset); 670 } else { 671 /* 672 * 0 1 2 3 673 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 674 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 675 * | Signal Byte | | 676 * +-+-+-+-+-+-+-+-+ IV | 677 * | | 678 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 679 * | | | 680 * |-+-+-+-+-+-+-+-+ | 681 * : Bytes 1..N of encrypted frame : 682 * | | 683 * | | 684 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 685 */ 686 int32_t plainSizes[] = { 0 }; 687 int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) }; 688 meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); 689 meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); 690 mbuf->set_range(9, mbuf->range_length() - 9); 691 } 692 } else { 693 /* 694 * 0 1 2 3 695 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 696 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 697 * | Signal Byte | | 698 * +-+-+-+-+-+-+-+-+ | 699 * : Bytes 1..N of unencrypted frame : 700 * | | 701 * | | 702 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 703 */ 704 int32_t plainSizes[] = { static_cast<int32_t>(mbuf->range_length() - 1) }; 705 int32_t encryptedSizes[] = { 0 }; 706 meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); 707 meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); 708 mbuf->set_range(1, mbuf->range_length() - 1); 709 } 710 711 return OK; 712 } 713 714 status_t MatroskaSource::readBlock() { 715 CHECK(mPendingFrames.empty()); 716 717 if (mBlockIter.eos()) { 718 return ERROR_END_OF_STREAM; 719 } 720 721 const mkvparser::Block *block = mBlockIter.block(); 722 723 int64_t timeUs = mBlockIter.blockTimeUs(); 724 725 for (int i = 0; i < block->GetFrameCount(); ++i) { 726 MatroskaExtractor::TrackInfo *trackInfo = &mExtractor->mTracks.editItemAt(mTrackIndex); 727 const mkvparser::Block::Frame &frame = block->GetFrame(i); 728 size_t len = frame.len; 729 if (SIZE_MAX - len < trackInfo->mHeaderLen) { 730 return ERROR_MALFORMED; 731 } 732 733 len += trackInfo->mHeaderLen; 734 MediaBufferBase *mbuf = MediaBufferBase::Create(len); 735 uint8_t *data = static_cast<uint8_t *>(mbuf->data()); 736 if (trackInfo->mHeader) { 737 memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen); 738 } 739 740 mbuf->meta_data().setInt64(kKeyTime, timeUs); 741 mbuf->meta_data().setInt32(kKeyIsSyncFrame, block->IsKey()); 742 743 status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen); 744 if (err == OK 745 && mExtractor->mIsWebm 746 && trackInfo->mEncrypted) { 747 err = setWebmBlockCryptoInfo(mbuf); 748 } 749 750 if (err != OK) { 751 mPendingFrames.clear(); 752 753 mBlockIter.advance(); 754 mbuf->release(); 755 return err; 756 } 757 758 mPendingFrames.push_back(mbuf); 759 } 760 761 mBlockIter.advance(); 762 763 return OK; 764 } 765 766 status_t MatroskaSource::read( 767 MediaBufferBase **out, const ReadOptions *options) { 768 *out = NULL; 769 770 int64_t targetSampleTimeUs = -1ll; 771 772 int64_t seekTimeUs; 773 ReadOptions::SeekMode mode; 774 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 775 if (mode == ReadOptions::SEEK_FRAME_INDEX) { 776 return ERROR_UNSUPPORTED; 777 } 778 779 if (!mExtractor->isLiveStreaming()) { 780 clearPendingFrames(); 781 782 // The audio we want is located by using the Cues to seek the video 783 // stream to find the target Cluster then iterating to finalize for 784 // audio. 785 int64_t actualFrameTimeUs; 786 mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs); 787 if (mode == ReadOptions::SEEK_CLOSEST) { 788 targetSampleTimeUs = actualFrameTimeUs; 789 } 790 } 791 } 792 793 while (mPendingFrames.empty()) { 794 status_t err = readBlock(); 795 796 if (err != OK) { 797 clearPendingFrames(); 798 799 return err; 800 } 801 } 802 803 MediaBufferBase *frame = *mPendingFrames.begin(); 804 mPendingFrames.erase(mPendingFrames.begin()); 805 806 if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) { 807 if (targetSampleTimeUs >= 0ll) { 808 frame->meta_data().setInt64( 809 kKeyTargetTime, targetSampleTimeUs); 810 } 811 812 *out = frame; 813 814 return OK; 815 } 816 817 // Each input frame contains one or more NAL fragments, each fragment 818 // is prefixed by mNALSizeLen bytes giving the fragment length, 819 // followed by a corresponding number of bytes containing the fragment. 820 // We output all these fragments into a single large buffer separated 821 // by startcodes (0x00 0x00 0x00 0x01). 822 // 823 // When mNALSizeLen is 0, we assume the data is already in the format 824 // desired. 825 826 const uint8_t *srcPtr = 827 (const uint8_t *)frame->data() + frame->range_offset(); 828 829 size_t srcSize = frame->range_length(); 830 831 size_t dstSize = 0; 832 MediaBufferBase *buffer = NULL; 833 uint8_t *dstPtr = NULL; 834 835 for (int32_t pass = 0; pass < 2; ++pass) { 836 size_t srcOffset = 0; 837 size_t dstOffset = 0; 838 while (srcOffset + mNALSizeLen <= srcSize) { 839 size_t NALsize; 840 switch (mNALSizeLen) { 841 case 1: NALsize = srcPtr[srcOffset]; break; 842 case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 843 case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 844 case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 845 default: 846 TRESPASS(); 847 } 848 849 if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) { 850 frame->release(); 851 frame = NULL; 852 853 return ERROR_MALFORMED; 854 } else if (srcOffset + mNALSizeLen + NALsize > srcSize) { 855 break; 856 } 857 858 if (pass == 1) { 859 memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 860 861 if (frame != buffer) { 862 memcpy(&dstPtr[dstOffset + 4], 863 &srcPtr[srcOffset + mNALSizeLen], 864 NALsize); 865 } 866 } 867 868 dstOffset += 4; // 0x00 00 00 01 869 dstOffset += NALsize; 870 871 srcOffset += mNALSizeLen + NALsize; 872 } 873 874 if (srcOffset < srcSize) { 875 // There were trailing bytes or not enough data to complete 876 // a fragment. 877 878 frame->release(); 879 frame = NULL; 880 881 return ERROR_MALFORMED; 882 } 883 884 if (pass == 0) { 885 dstSize = dstOffset; 886 887 if (dstSize == srcSize && mNALSizeLen == 4) { 888 // In this special case we can re-use the input buffer by substituting 889 // each 4-byte nal size with a 4-byte start code 890 buffer = frame; 891 } else { 892 buffer = MediaBufferBase::Create(dstSize); 893 } 894 895 int64_t timeUs; 896 CHECK(frame->meta_data().findInt64(kKeyTime, &timeUs)); 897 int32_t isSync; 898 CHECK(frame->meta_data().findInt32(kKeyIsSyncFrame, &isSync)); 899 900 buffer->meta_data().setInt64(kKeyTime, timeUs); 901 buffer->meta_data().setInt32(kKeyIsSyncFrame, isSync); 902 903 dstPtr = (uint8_t *)buffer->data(); 904 } 905 } 906 907 if (frame != buffer) { 908 frame->release(); 909 frame = NULL; 910 } 911 912 if (targetSampleTimeUs >= 0ll) { 913 buffer->meta_data().setInt64( 914 kKeyTargetTime, targetSampleTimeUs); 915 } 916 917 *out = buffer; 918 919 return OK; 920 } 921 922 //////////////////////////////////////////////////////////////////////////////// 923 924 MatroskaExtractor::MatroskaExtractor(DataSourceBase *source) 925 : mDataSource(source), 926 mReader(new DataSourceBaseReader(mDataSource)), 927 mSegment(NULL), 928 mExtractedThumbnails(false), 929 mIsWebm(false), 930 mSeekPreRollNs(0) { 931 off64_t size; 932 mIsLiveStreaming = 933 (mDataSource->flags() 934 & (DataSourceBase::kWantsPrefetching 935 | DataSourceBase::kIsCachingDataSource)) 936 && mDataSource->getSize(&size) != OK; 937 938 mkvparser::EBMLHeader ebmlHeader; 939 long long pos; 940 if (ebmlHeader.Parse(mReader, pos) < 0) { 941 return; 942 } 943 944 if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) { 945 mIsWebm = true; 946 } 947 948 long long ret = 949 mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 950 951 if (ret) { 952 CHECK(mSegment == NULL); 953 return; 954 } 955 956 // from mkvparser::Segment::Load(), but stop at first cluster 957 ret = mSegment->ParseHeaders(); 958 if (ret == 0) { 959 long len; 960 ret = mSegment->LoadCluster(pos, len); 961 if (ret >= 1) { 962 // no more clusters 963 ret = 0; 964 } 965 } else if (ret > 0) { 966 ret = mkvparser::E_BUFFER_NOT_FULL; 967 } 968 969 if (ret < 0) { 970 char uri[1024]; 971 if(!mDataSource->getUri(uri, sizeof(uri))) { 972 uri[0] = '\0'; 973 } 974 ALOGW("Corrupt %s source: %s", mIsWebm ? "webm" : "matroska", 975 uriDebugString(uri).c_str()); 976 delete mSegment; 977 mSegment = NULL; 978 return; 979 } 980 981 #if 0 982 const mkvparser::SegmentInfo *info = mSegment->GetInfo(); 983 ALOGI("muxing app: %s, writing app: %s", 984 info->GetMuxingAppAsUTF8(), 985 info->GetWritingAppAsUTF8()); 986 #endif 987 988 addTracks(); 989 } 990 991 MatroskaExtractor::~MatroskaExtractor() { 992 delete mSegment; 993 mSegment = NULL; 994 995 delete mReader; 996 mReader = NULL; 997 } 998 999 size_t MatroskaExtractor::countTracks() { 1000 return mTracks.size(); 1001 } 1002 1003 MediaTrack *MatroskaExtractor::getTrack(size_t index) { 1004 if (index >= mTracks.size()) { 1005 return NULL; 1006 } 1007 1008 return new MatroskaSource(this, index); 1009 } 1010 1011 status_t MatroskaExtractor::getTrackMetaData( 1012 MetaDataBase &meta, 1013 size_t index, uint32_t flags) { 1014 if (index >= mTracks.size()) { 1015 return UNKNOWN_ERROR; 1016 } 1017 1018 if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails 1019 && !isLiveStreaming()) { 1020 findThumbnails(); 1021 mExtractedThumbnails = true; 1022 } 1023 1024 meta = mTracks.itemAt(index).mMeta; 1025 return OK; 1026 } 1027 1028 bool MatroskaExtractor::isLiveStreaming() const { 1029 return mIsLiveStreaming; 1030 } 1031 1032 static int bytesForSize(size_t size) { 1033 // use at most 28 bits (4 times 7) 1034 CHECK(size <= 0xfffffff); 1035 1036 if (size > 0x1fffff) { 1037 return 4; 1038 } else if (size > 0x3fff) { 1039 return 3; 1040 } else if (size > 0x7f) { 1041 return 2; 1042 } 1043 return 1; 1044 } 1045 1046 static void storeSize(uint8_t *data, size_t &idx, size_t size) { 1047 int numBytes = bytesForSize(size); 1048 idx += numBytes; 1049 1050 data += idx; 1051 size_t next = 0; 1052 while (numBytes--) { 1053 *--data = (size & 0x7f) | next; 1054 size >>= 7; 1055 next = 0x80; 1056 } 1057 } 1058 1059 static void addESDSFromCodecPrivate( 1060 MetaDataBase &meta, 1061 bool isAudio, const void *priv, size_t privSize) { 1062 1063 int privSizeBytesRequired = bytesForSize(privSize); 1064 int esdsSize2 = 14 + privSizeBytesRequired + privSize; 1065 int esdsSize2BytesRequired = bytesForSize(esdsSize2); 1066 int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2; 1067 int esdsSize1BytesRequired = bytesForSize(esdsSize1); 1068 size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1; 1069 uint8_t *esds = new uint8_t[esdsSize]; 1070 1071 size_t idx = 0; 1072 esds[idx++] = 0x03; 1073 storeSize(esds, idx, esdsSize1); 1074 esds[idx++] = 0x00; // ES_ID 1075 esds[idx++] = 0x00; // ES_ID 1076 esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 1077 esds[idx++] = 0x04; 1078 storeSize(esds, idx, esdsSize2); 1079 esds[idx++] = isAudio ? 0x40 // Audio ISO/IEC 14496-3 1080 : 0x20; // Visual ISO/IEC 14496-2 1081 for (int i = 0; i < 12; i++) { 1082 esds[idx++] = 0x00; 1083 } 1084 esds[idx++] = 0x05; 1085 storeSize(esds, idx, privSize); 1086 memcpy(esds + idx, priv, privSize); 1087 1088 meta.setData(kKeyESDS, 0, esds, esdsSize); 1089 1090 delete[] esds; 1091 esds = NULL; 1092 } 1093 1094 status_t addVorbisCodecInfo( 1095 MetaDataBase &meta, 1096 const void *_codecPrivate, size_t codecPrivateSize) { 1097 // hexdump(_codecPrivate, codecPrivateSize); 1098 1099 if (codecPrivateSize < 1) { 1100 return ERROR_MALFORMED; 1101 } 1102 1103 const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 1104 1105 if (codecPrivate[0] != 0x02) { 1106 return ERROR_MALFORMED; 1107 } 1108 1109 // codecInfo starts with two lengths, len1 and len2, that are 1110 // "Xiph-style-lacing encoded"... 1111 1112 size_t offset = 1; 1113 size_t len1 = 0; 1114 while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) { 1115 if (len1 > (SIZE_MAX - 0xff)) { 1116 return ERROR_MALFORMED; // would overflow 1117 } 1118 len1 += 0xff; 1119 ++offset; 1120 } 1121 if (offset >= codecPrivateSize) { 1122 return ERROR_MALFORMED; 1123 } 1124 if (len1 > (SIZE_MAX - codecPrivate[offset])) { 1125 return ERROR_MALFORMED; // would overflow 1126 } 1127 len1 += codecPrivate[offset++]; 1128 1129 size_t len2 = 0; 1130 while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) { 1131 if (len2 > (SIZE_MAX - 0xff)) { 1132 return ERROR_MALFORMED; // would overflow 1133 } 1134 len2 += 0xff; 1135 ++offset; 1136 } 1137 if (offset >= codecPrivateSize) { 1138 return ERROR_MALFORMED; 1139 } 1140 if (len2 > (SIZE_MAX - codecPrivate[offset])) { 1141 return ERROR_MALFORMED; // would overflow 1142 } 1143 len2 += codecPrivate[offset++]; 1144 1145 if (len1 > SIZE_MAX - len2 || offset > SIZE_MAX - (len1 + len2) || 1146 codecPrivateSize < offset + len1 + len2) { 1147 return ERROR_MALFORMED; 1148 } 1149 1150 if (codecPrivate[offset] != 0x01) { 1151 return ERROR_MALFORMED; 1152 } 1153 meta.setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1); 1154 1155 offset += len1; 1156 if (codecPrivate[offset] != 0x03) { 1157 return ERROR_MALFORMED; 1158 } 1159 1160 offset += len2; 1161 if (codecPrivate[offset] != 0x05) { 1162 return ERROR_MALFORMED; 1163 } 1164 1165 meta.setData( 1166 kKeyVorbisBooks, 0, &codecPrivate[offset], 1167 codecPrivateSize - offset); 1168 1169 return OK; 1170 } 1171 1172 static status_t addFlacMetadata( 1173 MetaDataBase &meta, 1174 const void *codecPrivate, size_t codecPrivateSize) { 1175 // hexdump(codecPrivate, codecPrivateSize); 1176 1177 meta.setData(kKeyFlacMetadata, 0, codecPrivate, codecPrivateSize); 1178 1179 int32_t maxInputSize = 64 << 10; 1180 FLACDecoder *flacDecoder = FLACDecoder::Create(); 1181 if (flacDecoder != NULL 1182 && flacDecoder->parseMetadata((const uint8_t*)codecPrivate, codecPrivateSize) == OK) { 1183 FLAC__StreamMetadata_StreamInfo streamInfo = flacDecoder->getStreamInfo(); 1184 maxInputSize = streamInfo.max_framesize; 1185 if (maxInputSize == 0) { 1186 // In case max framesize is not available, use raw data size as max framesize, 1187 // assuming there is no expansion. 1188 if (streamInfo.max_blocksize != 0 1189 && streamInfo.channels != 0 1190 && ((streamInfo.bits_per_sample + 7) / 8) > 1191 INT32_MAX / streamInfo.max_blocksize / streamInfo.channels) { 1192 delete flacDecoder; 1193 return ERROR_MALFORMED; 1194 } 1195 maxInputSize = ((streamInfo.bits_per_sample + 7) / 8) 1196 * streamInfo.max_blocksize * streamInfo.channels; 1197 } 1198 } 1199 meta.setInt32(kKeyMaxInputSize, maxInputSize); 1200 1201 delete flacDecoder; 1202 return OK; 1203 } 1204 1205 status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { 1206 BlockIterator iter(this, trackInfo->mTrackNum, index); 1207 if (iter.eos()) { 1208 return ERROR_MALFORMED; 1209 } 1210 1211 const mkvparser::Block *block = iter.block(); 1212 if (block->GetFrameCount() <= 0) { 1213 return ERROR_MALFORMED; 1214 } 1215 1216 const mkvparser::Block::Frame &frame = block->GetFrame(0); 1217 auto tmpData = heapbuffer<unsigned char>(frame.len); 1218 long n = frame.Read(mReader, tmpData.get()); 1219 if (n != 0) { 1220 return ERROR_MALFORMED; 1221 } 1222 1223 if (!MakeAVCCodecSpecificData(trackInfo->mMeta, tmpData.get(), frame.len)) { 1224 return ERROR_MALFORMED; 1225 } 1226 1227 // Override the synthesized nal length size, which is arbitrary 1228 trackInfo->mMeta.setInt32(kKeyNalLengthSize, 0); 1229 return OK; 1230 } 1231 1232 static inline bool isValidInt32ColourValue(long long value) { 1233 return value != mkvparser::Colour::kValueNotPresent 1234 && value >= INT32_MIN 1235 && value <= INT32_MAX; 1236 } 1237 1238 static inline bool isValidUint16ColourValue(long long value) { 1239 return value != mkvparser::Colour::kValueNotPresent 1240 && value >= 0 1241 && value <= UINT16_MAX; 1242 } 1243 1244 static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) { 1245 return primary != NULL && primary->x >= 0 && primary->x <= 1 1246 && primary->y >= 0 && primary->y <= 1; 1247 } 1248 1249 void MatroskaExtractor::getColorInformation( 1250 const mkvparser::VideoTrack *vtrack, MetaDataBase &meta) { 1251 const mkvparser::Colour *color = vtrack->GetColour(); 1252 if (color == NULL) { 1253 return; 1254 } 1255 1256 // Color Aspects 1257 { 1258 int32_t primaries = 2; // ISO unspecified 1259 int32_t transfer = 2; // ISO unspecified 1260 int32_t coeffs = 2; // ISO unspecified 1261 bool fullRange = false; // default 1262 bool rangeSpecified = false; 1263 1264 if (isValidInt32ColourValue(color->primaries)) { 1265 primaries = color->primaries; 1266 } 1267 if (isValidInt32ColourValue(color->transfer_characteristics)) { 1268 transfer = color->transfer_characteristics; 1269 } 1270 if (isValidInt32ColourValue(color->matrix_coefficients)) { 1271 coeffs = color->matrix_coefficients; 1272 } 1273 if (color->range != mkvparser::Colour::kValueNotPresent 1274 && color->range != 0 /* MKV unspecified */) { 1275 // We only support MKV broadcast range (== limited) and full range. 1276 // We treat all other value as the default limited range. 1277 fullRange = color->range == 2 /* MKV fullRange */; 1278 rangeSpecified = true; 1279 } 1280 1281 ColorAspects aspects; 1282 ColorUtils::convertIsoColorAspectsToCodecAspects( 1283 primaries, transfer, coeffs, fullRange, aspects); 1284 meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries); 1285 meta.setInt32(kKeyTransferFunction, aspects.mTransfer); 1286 meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); 1287 meta.setInt32( 1288 kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified); 1289 } 1290 1291 // HDR Static Info 1292 { 1293 HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info 1294 memset(&info, 0, sizeof(info)); 1295 memset(&nullInfo, 0, sizeof(nullInfo)); 1296 if (isValidUint16ColourValue(color->max_cll)) { 1297 info.sType1.mMaxContentLightLevel = color->max_cll; 1298 } 1299 if (isValidUint16ColourValue(color->max_fall)) { 1300 info.sType1.mMaxFrameAverageLightLevel = color->max_fall; 1301 } 1302 const mkvparser::MasteringMetadata *mastering = color->mastering_metadata; 1303 if (mastering != NULL) { 1304 // Convert matroska values to HDRStaticInfo equivalent values for each fully specified 1305 // group. See CTA-681.3 section 3.2.1 for more info. 1306 if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) { 1307 info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5); 1308 } 1309 if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) { 1310 // HDRStaticInfo Type1 stores min luminance scaled 10000:1 1311 info.sType1.mMinDisplayLuminance = 1312 (uint16_t)(10000 * mastering->luminance_min + 0.5); 1313 } 1314 // HDRStaticInfo Type1 stores primaries scaled 50000:1 1315 if (isValidPrimary(mastering->white_point)) { 1316 info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5); 1317 info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5); 1318 } 1319 if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g) 1320 && isValidPrimary(mastering->b)) { 1321 info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5); 1322 info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5); 1323 info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5); 1324 info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5); 1325 info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5); 1326 info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5); 1327 } 1328 } 1329 // Only advertise static info if at least one of the groups have been specified. 1330 if (memcmp(&info, &nullInfo, sizeof(info)) != 0) { 1331 info.mID = HDRStaticInfo::kType1; 1332 meta.setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); 1333 } 1334 } 1335 } 1336 1337 status_t MatroskaExtractor::initTrackInfo( 1338 const mkvparser::Track *track, MetaDataBase &meta, TrackInfo *trackInfo) { 1339 trackInfo->mTrackNum = track->GetNumber(); 1340 trackInfo->mMeta = meta; 1341 trackInfo->mExtractor = this; 1342 trackInfo->mEncrypted = false; 1343 trackInfo->mHeader = NULL; 1344 trackInfo->mHeaderLen = 0; 1345 1346 for(size_t i = 0; i < track->GetContentEncodingCount(); i++) { 1347 const mkvparser::ContentEncoding *encoding = track->GetContentEncodingByIndex(i); 1348 for(size_t j = 0; j < encoding->GetEncryptionCount(); j++) { 1349 const mkvparser::ContentEncoding::ContentEncryption *encryption; 1350 encryption = encoding->GetEncryptionByIndex(j); 1351 trackInfo->mMeta.setData(kKeyCryptoKey, 0, encryption->key_id, encryption->key_id_len); 1352 trackInfo->mEncrypted = true; 1353 break; 1354 } 1355 1356 for(size_t j = 0; j < encoding->GetCompressionCount(); j++) { 1357 const mkvparser::ContentEncoding::ContentCompression *compression; 1358 compression = encoding->GetCompressionByIndex(j); 1359 ALOGV("compression algo %llu settings_len %lld", 1360 compression->algo, compression->settings_len); 1361 if (compression->algo == 3 1362 && compression->settings 1363 && compression->settings_len > 0) { 1364 trackInfo->mHeader = compression->settings; 1365 trackInfo->mHeaderLen = compression->settings_len; 1366 } 1367 } 1368 } 1369 1370 return OK; 1371 } 1372 1373 void MatroskaExtractor::addTracks() { 1374 const mkvparser::Tracks *tracks = mSegment->GetTracks(); 1375 1376 for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 1377 const mkvparser::Track *track = tracks->GetTrackByIndex(index); 1378 1379 if (track == NULL) { 1380 // Apparently this is currently valid (if unexpected) behaviour 1381 // of the mkv parser lib. 1382 continue; 1383 } 1384 1385 const char *const codecID = track->GetCodecId(); 1386 ALOGV("codec id = %s", codecID); 1387 ALOGV("codec name = %s", track->GetCodecNameAsUTF8()); 1388 1389 if (codecID == NULL) { 1390 ALOGW("unknown codecID is not supported."); 1391 continue; 1392 } 1393 1394 size_t codecPrivateSize; 1395 const unsigned char *codecPrivate = 1396 track->GetCodecPrivate(codecPrivateSize); 1397 1398 enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 1399 1400 MetaDataBase meta; 1401 1402 status_t err = OK; 1403 1404 switch (track->GetType()) { 1405 case VIDEO_TRACK: 1406 { 1407 const mkvparser::VideoTrack *vtrack = 1408 static_cast<const mkvparser::VideoTrack *>(track); 1409 1410 if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 1411 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1412 meta.setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 1413 } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) { 1414 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC); 1415 if (codecPrivateSize > 0) { 1416 meta.setData(kKeyHVCC, kTypeHVCC, codecPrivate, codecPrivateSize); 1417 } else { 1418 ALOGW("HEVC is detected, but does not have configuration."); 1419 continue; 1420 } 1421 } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { 1422 if (codecPrivateSize > 0) { 1423 meta.setCString( 1424 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1425 addESDSFromCodecPrivate( 1426 meta, false, codecPrivate, codecPrivateSize); 1427 } else { 1428 ALOGW("%s is detected, but does not have configuration.", 1429 codecID); 1430 continue; 1431 } 1432 } else if (!strcmp("V_VP8", codecID)) { 1433 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); 1434 } else if (!strcmp("V_VP9", codecID)) { 1435 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); 1436 if (codecPrivateSize > 0) { 1437 // 'csd-0' for VP9 is the Blob of Codec Private data as 1438 // specified in http://www.webmproject.org/vp9/profiles/. 1439 meta.setData( 1440 kKeyVp9CodecPrivate, 0, codecPrivate, 1441 codecPrivateSize); 1442 } 1443 } else { 1444 ALOGW("%s is not supported.", codecID); 1445 continue; 1446 } 1447 1448 const long long width = vtrack->GetWidth(); 1449 const long long height = vtrack->GetHeight(); 1450 if (width <= 0 || width > INT32_MAX) { 1451 ALOGW("track width exceeds int32_t, %lld", width); 1452 continue; 1453 } 1454 if (height <= 0 || height > INT32_MAX) { 1455 ALOGW("track height exceeds int32_t, %lld", height); 1456 continue; 1457 } 1458 meta.setInt32(kKeyWidth, (int32_t)width); 1459 meta.setInt32(kKeyHeight, (int32_t)height); 1460 1461 // setting display width/height is optional 1462 const long long displayUnit = vtrack->GetDisplayUnit(); 1463 const long long displayWidth = vtrack->GetDisplayWidth(); 1464 const long long displayHeight = vtrack->GetDisplayHeight(); 1465 if (displayWidth > 0 && displayWidth <= INT32_MAX 1466 && displayHeight > 0 && displayHeight <= INT32_MAX) { 1467 switch (displayUnit) { 1468 case 0: // pixels 1469 meta.setInt32(kKeyDisplayWidth, (int32_t)displayWidth); 1470 meta.setInt32(kKeyDisplayHeight, (int32_t)displayHeight); 1471 break; 1472 case 1: // centimeters 1473 case 2: // inches 1474 case 3: // aspect ratio 1475 { 1476 // Physical layout size is treated the same as aspect ratio. 1477 // Note: displayWidth and displayHeight are never zero as they are 1478 // checked in the if above. 1479 const long long computedWidth = 1480 std::max(width, height * displayWidth / displayHeight); 1481 const long long computedHeight = 1482 std::max(height, width * displayHeight / displayWidth); 1483 if (computedWidth <= INT32_MAX && computedHeight <= INT32_MAX) { 1484 meta.setInt32(kKeyDisplayWidth, (int32_t)computedWidth); 1485 meta.setInt32(kKeyDisplayHeight, (int32_t)computedHeight); 1486 } 1487 break; 1488 } 1489 default: // unknown display units, perhaps future version of spec. 1490 break; 1491 } 1492 } 1493 1494 getColorInformation(vtrack, meta); 1495 1496 break; 1497 } 1498 1499 case AUDIO_TRACK: 1500 { 1501 const mkvparser::AudioTrack *atrack = 1502 static_cast<const mkvparser::AudioTrack *>(track); 1503 1504 if (!strcmp("A_AAC", codecID)) { 1505 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 1506 CHECK(codecPrivateSize >= 2); 1507 1508 addESDSFromCodecPrivate( 1509 meta, true, codecPrivate, codecPrivateSize); 1510 } else if (!strcmp("A_VORBIS", codecID)) { 1511 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 1512 1513 err = addVorbisCodecInfo( 1514 meta, codecPrivate, codecPrivateSize); 1515 } else if (!strcmp("A_OPUS", codecID)) { 1516 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_OPUS); 1517 meta.setData(kKeyOpusHeader, 0, codecPrivate, codecPrivateSize); 1518 meta.setInt64(kKeyOpusCodecDelay, track->GetCodecDelay()); 1519 meta.setInt64(kKeyOpusSeekPreRoll, track->GetSeekPreRoll()); 1520 mSeekPreRollNs = track->GetSeekPreRoll(); 1521 } else if (!strcmp("A_MPEG/L3", codecID)) { 1522 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 1523 } else if (!strcmp("A_FLAC", codecID)) { 1524 meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); 1525 err = addFlacMetadata(meta, codecPrivate, codecPrivateSize); 1526 } else { 1527 ALOGW("%s is not supported.", codecID); 1528 continue; 1529 } 1530 1531 meta.setInt32(kKeySampleRate, atrack->GetSamplingRate()); 1532 meta.setInt32(kKeyChannelCount, atrack->GetChannels()); 1533 break; 1534 } 1535 1536 default: 1537 continue; 1538 } 1539 1540 const char *language = track->GetLanguage(); 1541 if (language != NULL) { 1542 char lang[4]; 1543 strncpy(lang, language, 3); 1544 lang[3] = '\0'; 1545 meta.setCString(kKeyMediaLanguage, lang); 1546 } 1547 1548 if (err != OK) { 1549 ALOGE("skipping track, codec specific data was malformed."); 1550 continue; 1551 } 1552 1553 long long durationNs = mSegment->GetDuration(); 1554 meta.setInt64(kKeyDuration, (durationNs + 500) / 1000); 1555 1556 mTracks.push(); 1557 size_t n = mTracks.size() - 1; 1558 TrackInfo *trackInfo = &mTracks.editItemAt(n); 1559 initTrackInfo(track, meta, trackInfo); 1560 1561 if (!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) { 1562 // Attempt to recover from AVC track without codec private data 1563 err = synthesizeAVCC(trackInfo, n); 1564 if (err != OK) { 1565 mTracks.pop(); 1566 } 1567 } 1568 } 1569 } 1570 1571 void MatroskaExtractor::findThumbnails() { 1572 for (size_t i = 0; i < mTracks.size(); ++i) { 1573 TrackInfo *info = &mTracks.editItemAt(i); 1574 1575 const char *mime; 1576 CHECK(info->mMeta.findCString(kKeyMIMEType, &mime)); 1577 1578 if (strncasecmp(mime, "video/", 6)) { 1579 continue; 1580 } 1581 1582 BlockIterator iter(this, info->mTrackNum, i); 1583 int32_t j = 0; 1584 int64_t thumbnailTimeUs = 0; 1585 size_t maxBlockSize = 0; 1586 while (!iter.eos() && j < 20) { 1587 if (iter.block()->IsKey()) { 1588 ++j; 1589 1590 size_t blockSize = 0; 1591 for (int k = 0; k < iter.block()->GetFrameCount(); ++k) { 1592 blockSize += iter.block()->GetFrame(k).len; 1593 } 1594 1595 if (blockSize > maxBlockSize) { 1596 maxBlockSize = blockSize; 1597 thumbnailTimeUs = iter.blockTimeUs(); 1598 } 1599 } 1600 iter.advance(); 1601 } 1602 info->mMeta.setInt64(kKeyThumbnailTime, thumbnailTimeUs); 1603 } 1604 } 1605 1606 status_t MatroskaExtractor::getMetaData(MetaDataBase &meta) { 1607 meta.setCString( 1608 kKeyMIMEType, 1609 mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA); 1610 1611 return OK; 1612 } 1613 1614 uint32_t MatroskaExtractor::flags() const { 1615 uint32_t x = CAN_PAUSE; 1616 if (!isLiveStreaming()) { 1617 x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK; 1618 } 1619 1620 return x; 1621 } 1622 1623 bool SniffMatroska( 1624 DataSourceBase *source, float *confidence) { 1625 DataSourceBaseReader reader(source); 1626 mkvparser::EBMLHeader ebmlHeader; 1627 long long pos; 1628 if (ebmlHeader.Parse(&reader, pos) < 0) { 1629 return false; 1630 } 1631 1632 *confidence = 0.6; 1633 1634 return true; 1635 } 1636 1637 1638 extern "C" { 1639 // This is the only symbol that needs to be exported 1640 __attribute__ ((visibility ("default"))) 1641 MediaExtractor::ExtractorDef GETEXTRACTORDEF() { 1642 return { 1643 MediaExtractor::EXTRACTORDEF_VERSION, 1644 UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"), 1645 1, 1646 "Matroska Extractor", 1647 []( 1648 DataSourceBase *source, 1649 float *confidence, 1650 void **, 1651 MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc { 1652 if (SniffMatroska(source, confidence)) { 1653 return []( 1654 DataSourceBase *source, 1655 void *) -> MediaExtractor* { 1656 return new MatroskaExtractor(source);}; 1657 } 1658 return NULL; 1659 } 1660 }; 1661 } 1662 1663 } // extern "C" 1664 1665 } // namespace android 1666