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 "MatroskaExtractor.h" 22 23 #include <media/stagefright/foundation/ADebug.h> 24 #include <media/stagefright/foundation/AUtils.h> 25 #include <media/stagefright/foundation/hexdump.h> 26 #include <media/stagefright/DataSource.h> 27 #include <media/stagefright/MediaBuffer.h> 28 #include <media/stagefright/MediaDefs.h> 29 #include <media/stagefright/MediaErrors.h> 30 #include <media/stagefright/MediaSource.h> 31 #include <media/stagefright/MetaData.h> 32 #include <media/stagefright/Utils.h> 33 #include <utils/String8.h> 34 35 #include <inttypes.h> 36 37 namespace android { 38 39 struct DataSourceReader : public mkvparser::IMkvReader { 40 DataSourceReader(const sp<DataSource> &source) 41 : mSource(source) { 42 } 43 44 virtual int Read(long long position, long length, unsigned char* buffer) { 45 CHECK(position >= 0); 46 CHECK(length >= 0); 47 48 if (length == 0) { 49 return 0; 50 } 51 52 ssize_t n = mSource->readAt(position, buffer, length); 53 54 if (n <= 0) { 55 return -1; 56 } 57 58 return 0; 59 } 60 61 virtual int Length(long long* total, long long* available) { 62 off64_t size; 63 if (mSource->getSize(&size) != OK) { 64 *total = -1; 65 *available = (long long)((1ull << 63) - 1); 66 67 return 0; 68 } 69 70 if (total) { 71 *total = size; 72 } 73 74 if (available) { 75 *available = size; 76 } 77 78 return 0; 79 } 80 81 private: 82 sp<DataSource> mSource; 83 84 DataSourceReader(const DataSourceReader &); 85 DataSourceReader &operator=(const DataSourceReader &); 86 }; 87 88 //////////////////////////////////////////////////////////////////////////////// 89 90 struct BlockIterator { 91 BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index); 92 93 bool eos() const; 94 95 void advance(); 96 void reset(); 97 98 void seek( 99 int64_t seekTimeUs, bool isAudio, 100 int64_t *actualFrameTimeUs); 101 102 const mkvparser::Block *block() const; 103 int64_t blockTimeUs() const; 104 105 private: 106 MatroskaExtractor *mExtractor; 107 long long mTrackNum; 108 unsigned long mIndex; 109 110 const mkvparser::Cluster *mCluster; 111 const mkvparser::BlockEntry *mBlockEntry; 112 long mBlockEntryIndex; 113 114 void advance_l(); 115 116 BlockIterator(const BlockIterator &); 117 BlockIterator &operator=(const BlockIterator &); 118 }; 119 120 struct MatroskaSource : public MediaSource { 121 MatroskaSource( 122 const sp<MatroskaExtractor> &extractor, size_t index); 123 124 virtual status_t start(MetaData *params); 125 virtual status_t stop(); 126 127 virtual sp<MetaData> getFormat(); 128 129 virtual status_t read( 130 MediaBuffer **buffer, const ReadOptions *options); 131 132 protected: 133 virtual ~MatroskaSource(); 134 135 private: 136 enum Type { 137 AVC, 138 AAC, 139 OTHER 140 }; 141 142 sp<MatroskaExtractor> mExtractor; 143 size_t mTrackIndex; 144 Type mType; 145 bool mIsAudio; 146 BlockIterator mBlockIter; 147 size_t mNALSizeLen; // for type AVC 148 149 List<MediaBuffer *> mPendingFrames; 150 151 status_t advance(); 152 153 status_t readBlock(); 154 void clearPendingFrames(); 155 156 MatroskaSource(const MatroskaSource &); 157 MatroskaSource &operator=(const MatroskaSource &); 158 }; 159 160 const mkvparser::Track* MatroskaExtractor::TrackInfo::getTrack() const { 161 return mExtractor->mSegment->GetTracks()->GetTrackByNumber(mTrackNum); 162 } 163 164 // This function does exactly the same as mkvparser::Cues::Find, except that it 165 // searches in our own track based vectors. We should not need this once mkvparser 166 // adds the same functionality. 167 const mkvparser::CuePoint::TrackPosition *MatroskaExtractor::TrackInfo::find( 168 long long timeNs) const { 169 ALOGV("mCuePoints.size %zu", mCuePoints.size()); 170 if (mCuePoints.empty()) { 171 return NULL; 172 } 173 174 const mkvparser::CuePoint* cp = mCuePoints.itemAt(0); 175 const mkvparser::Track* track = getTrack(); 176 if (timeNs <= cp->GetTime(mExtractor->mSegment)) { 177 return cp->Find(track); 178 } 179 180 // Binary searches through relevant cues; assumes cues are ordered by timecode. 181 // If we do detect out-of-order cues, return NULL. 182 size_t lo = 0; 183 size_t hi = mCuePoints.size(); 184 while (lo < hi) { 185 const size_t mid = lo + (hi - lo) / 2; 186 const mkvparser::CuePoint* const midCp = mCuePoints.itemAt(mid); 187 const long long cueTimeNs = midCp->GetTime(mExtractor->mSegment); 188 if (cueTimeNs <= timeNs) { 189 lo = mid + 1; 190 } else { 191 hi = mid; 192 } 193 } 194 195 if (lo == 0) { 196 return NULL; 197 } 198 199 cp = mCuePoints.itemAt(lo - 1); 200 if (cp->GetTime(mExtractor->mSegment) > timeNs) { 201 return NULL; 202 } 203 204 return cp->Find(track); 205 } 206 207 MatroskaSource::MatroskaSource( 208 const sp<MatroskaExtractor> &extractor, size_t index) 209 : mExtractor(extractor), 210 mTrackIndex(index), 211 mType(OTHER), 212 mIsAudio(false), 213 mBlockIter(mExtractor.get(), 214 mExtractor->mTracks.itemAt(index).mTrackNum, 215 index), 216 mNALSizeLen(0) { 217 sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 218 219 const char *mime; 220 CHECK(meta->findCString(kKeyMIMEType, &mime)); 221 222 mIsAudio = !strncasecmp("audio/", mime, 6); 223 224 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 225 mType = AVC; 226 227 uint32_t dummy; 228 const uint8_t *avcc; 229 size_t avccSize; 230 CHECK(meta->findData( 231 kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 232 233 CHECK_GE(avccSize, 5u); 234 235 mNALSizeLen = 1 + (avcc[4] & 3); 236 ALOGV("mNALSizeLen = %zu", mNALSizeLen); 237 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 238 mType = AAC; 239 } 240 } 241 242 MatroskaSource::~MatroskaSource() { 243 clearPendingFrames(); 244 } 245 246 status_t MatroskaSource::start(MetaData * /* params */) { 247 mBlockIter.reset(); 248 249 return OK; 250 } 251 252 status_t MatroskaSource::stop() { 253 clearPendingFrames(); 254 255 return OK; 256 } 257 258 sp<MetaData> MatroskaSource::getFormat() { 259 return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 260 } 261 262 //////////////////////////////////////////////////////////////////////////////// 263 264 BlockIterator::BlockIterator( 265 MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index) 266 : mExtractor(extractor), 267 mTrackNum(trackNum), 268 mIndex(index), 269 mCluster(NULL), 270 mBlockEntry(NULL), 271 mBlockEntryIndex(0) { 272 reset(); 273 } 274 275 bool BlockIterator::eos() const { 276 return mCluster == NULL || mCluster->EOS(); 277 } 278 279 void BlockIterator::advance() { 280 Mutex::Autolock autoLock(mExtractor->mLock); 281 advance_l(); 282 } 283 284 void BlockIterator::advance_l() { 285 for (;;) { 286 long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); 287 ALOGV("GetEntry returned %ld", res); 288 289 long long pos; 290 long len; 291 if (res < 0) { 292 // Need to parse this cluster some more 293 294 CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); 295 296 res = mCluster->Parse(pos, len); 297 ALOGV("Parse returned %ld", res); 298 299 if (res < 0) { 300 // I/O error 301 302 ALOGE("Cluster::Parse returned result %ld", res); 303 304 mCluster = NULL; 305 break; 306 } 307 308 continue; 309 } else if (res == 0) { 310 // We're done with this cluster 311 312 const mkvparser::Cluster *nextCluster; 313 res = mExtractor->mSegment->ParseNext( 314 mCluster, nextCluster, pos, len); 315 ALOGV("ParseNext returned %ld", res); 316 317 if (res != 0) { 318 // EOF or error 319 320 mCluster = NULL; 321 break; 322 } 323 324 CHECK_EQ(res, 0); 325 CHECK(nextCluster != NULL); 326 CHECK(!nextCluster->EOS()); 327 328 mCluster = nextCluster; 329 330 res = mCluster->Parse(pos, len); 331 ALOGV("Parse (2) returned %ld", res); 332 CHECK_GE(res, 0); 333 334 mBlockEntryIndex = 0; 335 continue; 336 } 337 338 CHECK(mBlockEntry != NULL); 339 CHECK(mBlockEntry->GetBlock() != NULL); 340 ++mBlockEntryIndex; 341 342 if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 343 break; 344 } 345 } 346 } 347 348 void BlockIterator::reset() { 349 Mutex::Autolock autoLock(mExtractor->mLock); 350 351 mCluster = mExtractor->mSegment->GetFirst(); 352 mBlockEntry = NULL; 353 mBlockEntryIndex = 0; 354 355 do { 356 advance_l(); 357 } while (!eos() && block()->GetTrackNumber() != mTrackNum); 358 } 359 360 void BlockIterator::seek( 361 int64_t seekTimeUs, bool isAudio, 362 int64_t *actualFrameTimeUs) { 363 Mutex::Autolock autoLock(mExtractor->mLock); 364 365 *actualFrameTimeUs = -1ll; 366 367 const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs; 368 369 mkvparser::Segment* const pSegment = mExtractor->mSegment; 370 371 // Special case the 0 seek to avoid loading Cues when the application 372 // extraneously seeks to 0 before playing. 373 if (seekTimeNs <= 0) { 374 ALOGV("Seek to beginning: %" PRId64, seekTimeUs); 375 mCluster = pSegment->GetFirst(); 376 mBlockEntryIndex = 0; 377 do { 378 advance_l(); 379 } while (!eos() && block()->GetTrackNumber() != mTrackNum); 380 return; 381 } 382 383 ALOGV("Seeking to: %" PRId64, seekTimeUs); 384 385 // If the Cues have not been located then find them. 386 const mkvparser::Cues* pCues = pSegment->GetCues(); 387 const mkvparser::SeekHead* pSH = pSegment->GetSeekHead(); 388 if (!pCues && pSH) { 389 const size_t count = pSH->GetCount(); 390 const mkvparser::SeekHead::Entry* pEntry; 391 ALOGV("No Cues yet"); 392 393 for (size_t index = 0; index < count; index++) { 394 pEntry = pSH->GetEntry(index); 395 396 if (pEntry->id == 0x0C53BB6B) { // Cues ID 397 long len; long long pos; 398 pSegment->ParseCues(pEntry->pos, pos, len); 399 pCues = pSegment->GetCues(); 400 ALOGV("Cues found"); 401 break; 402 } 403 } 404 405 if (!pCues) { 406 ALOGE("No Cues in file"); 407 return; 408 } 409 } 410 else if (!pSH) { 411 ALOGE("No SeekHead"); 412 return; 413 } 414 415 const mkvparser::CuePoint* pCP; 416 mkvparser::Tracks const *pTracks = pSegment->GetTracks(); 417 while (!pCues->DoneParsing()) { 418 pCues->LoadCuePoint(); 419 pCP = pCues->GetLast(); 420 CHECK(pCP); 421 422 size_t trackCount = mExtractor->mTracks.size(); 423 for (size_t index = 0; index < trackCount; ++index) { 424 MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index); 425 const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum); 426 if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK 427 track.mCuePoints.push_back(pCP); 428 } 429 } 430 431 if (pCP->GetTime(pSegment) >= seekTimeNs) { 432 ALOGV("Parsed past relevant Cue"); 433 break; 434 } 435 } 436 437 const mkvparser::CuePoint::TrackPosition *pTP = NULL; 438 const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum); 439 if (thisTrack->GetType() == 1) { // video 440 MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex); 441 pTP = track.find(seekTimeNs); 442 } else { 443 // The Cue index is built around video keyframes 444 unsigned long int trackCount = pTracks->GetTracksCount(); 445 for (size_t index = 0; index < trackCount; ++index) { 446 const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index); 447 if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) { 448 ALOGV("Video track located at %zu", index); 449 break; 450 } 451 } 452 } 453 454 455 // Always *search* based on the video track, but finalize based on mTrackNum 456 if (!pTP) { 457 ALOGE("Did not locate the video track for seeking"); 458 return; 459 } 460 461 mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos); 462 463 CHECK(mCluster); 464 CHECK(!mCluster->EOS()); 465 466 // mBlockEntryIndex starts at 0 but m_block starts at 1 467 CHECK_GT(pTP->m_block, 0); 468 mBlockEntryIndex = pTP->m_block - 1; 469 470 for (;;) { 471 advance_l(); 472 473 if (eos()) break; 474 475 if (isAudio || block()->IsKey()) { 476 // Accept the first key frame 477 int64_t frameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL; 478 if (thisTrack->GetType() == 1 || frameTimeUs >= seekTimeUs) { 479 *actualFrameTimeUs = frameTimeUs; 480 ALOGV("Requested seek point: %" PRId64 " actual: %" PRId64, 481 seekTimeUs, *actualFrameTimeUs); 482 break; 483 } 484 } 485 } 486 } 487 488 const mkvparser::Block *BlockIterator::block() const { 489 CHECK(!eos()); 490 491 return mBlockEntry->GetBlock(); 492 } 493 494 int64_t BlockIterator::blockTimeUs() const { 495 return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 496 } 497 498 //////////////////////////////////////////////////////////////////////////////// 499 500 static unsigned U24_AT(const uint8_t *ptr) { 501 return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 502 } 503 504 void MatroskaSource::clearPendingFrames() { 505 while (!mPendingFrames.empty()) { 506 MediaBuffer *frame = *mPendingFrames.begin(); 507 mPendingFrames.erase(mPendingFrames.begin()); 508 509 frame->release(); 510 frame = NULL; 511 } 512 } 513 514 status_t MatroskaSource::readBlock() { 515 CHECK(mPendingFrames.empty()); 516 517 if (mBlockIter.eos()) { 518 return ERROR_END_OF_STREAM; 519 } 520 521 const mkvparser::Block *block = mBlockIter.block(); 522 523 int64_t timeUs = mBlockIter.blockTimeUs(); 524 525 for (int i = 0; i < block->GetFrameCount(); ++i) { 526 const mkvparser::Block::Frame &frame = block->GetFrame(i); 527 528 MediaBuffer *mbuf = new MediaBuffer(frame.len); 529 mbuf->meta_data()->setInt64(kKeyTime, timeUs); 530 mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); 531 532 long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data()); 533 if (n != 0) { 534 mPendingFrames.clear(); 535 536 mBlockIter.advance(); 537 return ERROR_IO; 538 } 539 540 mPendingFrames.push_back(mbuf); 541 } 542 543 mBlockIter.advance(); 544 545 return OK; 546 } 547 548 status_t MatroskaSource::read( 549 MediaBuffer **out, const ReadOptions *options) { 550 *out = NULL; 551 552 int64_t targetSampleTimeUs = -1ll; 553 554 int64_t seekTimeUs; 555 ReadOptions::SeekMode mode; 556 if (options && options->getSeekTo(&seekTimeUs, &mode) 557 && !mExtractor->isLiveStreaming()) { 558 clearPendingFrames(); 559 560 // The audio we want is located by using the Cues to seek the video 561 // stream to find the target Cluster then iterating to finalize for 562 // audio. 563 int64_t actualFrameTimeUs; 564 mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs); 565 566 if (mode == ReadOptions::SEEK_CLOSEST) { 567 targetSampleTimeUs = actualFrameTimeUs; 568 } 569 } 570 571 while (mPendingFrames.empty()) { 572 status_t err = readBlock(); 573 574 if (err != OK) { 575 clearPendingFrames(); 576 577 return err; 578 } 579 } 580 581 MediaBuffer *frame = *mPendingFrames.begin(); 582 mPendingFrames.erase(mPendingFrames.begin()); 583 584 if (mType != AVC) { 585 if (targetSampleTimeUs >= 0ll) { 586 frame->meta_data()->setInt64( 587 kKeyTargetTime, targetSampleTimeUs); 588 } 589 590 *out = frame; 591 592 return OK; 593 } 594 595 // Each input frame contains one or more NAL fragments, each fragment 596 // is prefixed by mNALSizeLen bytes giving the fragment length, 597 // followed by a corresponding number of bytes containing the fragment. 598 // We output all these fragments into a single large buffer separated 599 // by startcodes (0x00 0x00 0x00 0x01). 600 601 const uint8_t *srcPtr = 602 (const uint8_t *)frame->data() + frame->range_offset(); 603 604 size_t srcSize = frame->range_length(); 605 606 size_t dstSize = 0; 607 MediaBuffer *buffer = NULL; 608 uint8_t *dstPtr = NULL; 609 610 for (int32_t pass = 0; pass < 2; ++pass) { 611 size_t srcOffset = 0; 612 size_t dstOffset = 0; 613 while (srcOffset + mNALSizeLen <= srcSize) { 614 size_t NALsize; 615 switch (mNALSizeLen) { 616 case 1: NALsize = srcPtr[srcOffset]; break; 617 case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 618 case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 619 case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 620 default: 621 TRESPASS(); 622 } 623 624 if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) { 625 frame->release(); 626 frame = NULL; 627 628 return ERROR_MALFORMED; 629 } else if (srcOffset + mNALSizeLen + NALsize > srcSize) { 630 break; 631 } 632 633 if (pass == 1) { 634 memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 635 636 memcpy(&dstPtr[dstOffset + 4], 637 &srcPtr[srcOffset + mNALSizeLen], 638 NALsize); 639 } 640 641 dstOffset += 4; // 0x00 00 00 01 642 dstOffset += NALsize; 643 644 srcOffset += mNALSizeLen + NALsize; 645 } 646 647 if (srcOffset < srcSize) { 648 // There were trailing bytes or not enough data to complete 649 // a fragment. 650 651 frame->release(); 652 frame = NULL; 653 654 return ERROR_MALFORMED; 655 } 656 657 if (pass == 0) { 658 dstSize = dstOffset; 659 660 buffer = new MediaBuffer(dstSize); 661 662 int64_t timeUs; 663 CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 664 int32_t isSync; 665 CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); 666 667 buffer->meta_data()->setInt64(kKeyTime, timeUs); 668 buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 669 670 dstPtr = (uint8_t *)buffer->data(); 671 } 672 } 673 674 frame->release(); 675 frame = NULL; 676 677 if (targetSampleTimeUs >= 0ll) { 678 buffer->meta_data()->setInt64( 679 kKeyTargetTime, targetSampleTimeUs); 680 } 681 682 *out = buffer; 683 684 return OK; 685 } 686 687 //////////////////////////////////////////////////////////////////////////////// 688 689 MatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 690 : mDataSource(source), 691 mReader(new DataSourceReader(mDataSource)), 692 mSegment(NULL), 693 mExtractedThumbnails(false), 694 mIsWebm(false), 695 mSeekPreRollNs(0) { 696 off64_t size; 697 mIsLiveStreaming = 698 (mDataSource->flags() 699 & (DataSource::kWantsPrefetching 700 | DataSource::kIsCachingDataSource)) 701 && mDataSource->getSize(&size) != OK; 702 703 mkvparser::EBMLHeader ebmlHeader; 704 long long pos; 705 if (ebmlHeader.Parse(mReader, pos) < 0) { 706 return; 707 } 708 709 if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) { 710 mIsWebm = true; 711 } 712 713 long long ret = 714 mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 715 716 if (ret) { 717 CHECK(mSegment == NULL); 718 return; 719 } 720 721 // from mkvparser::Segment::Load(), but stop at first cluster 722 ret = mSegment->ParseHeaders(); 723 if (ret == 0) { 724 long len; 725 ret = mSegment->LoadCluster(pos, len); 726 if (ret >= 1) { 727 // no more clusters 728 ret = 0; 729 } 730 } else if (ret > 0) { 731 ret = mkvparser::E_BUFFER_NOT_FULL; 732 } 733 734 if (ret < 0) { 735 ALOGW("Corrupt %s source: %s", mIsWebm ? "webm" : "matroska", 736 uriDebugString(mDataSource->getUri()).c_str()); 737 delete mSegment; 738 mSegment = NULL; 739 return; 740 } 741 742 #if 0 743 const mkvparser::SegmentInfo *info = mSegment->GetInfo(); 744 ALOGI("muxing app: %s, writing app: %s", 745 info->GetMuxingAppAsUTF8(), 746 info->GetWritingAppAsUTF8()); 747 #endif 748 749 addTracks(); 750 } 751 752 MatroskaExtractor::~MatroskaExtractor() { 753 delete mSegment; 754 mSegment = NULL; 755 756 delete mReader; 757 mReader = NULL; 758 } 759 760 size_t MatroskaExtractor::countTracks() { 761 return mTracks.size(); 762 } 763 764 sp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 765 if (index >= mTracks.size()) { 766 return NULL; 767 } 768 769 return new MatroskaSource(this, index); 770 } 771 772 sp<MetaData> MatroskaExtractor::getTrackMetaData( 773 size_t index, uint32_t flags) { 774 if (index >= mTracks.size()) { 775 return NULL; 776 } 777 778 if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails 779 && !isLiveStreaming()) { 780 findThumbnails(); 781 mExtractedThumbnails = true; 782 } 783 784 return mTracks.itemAt(index).mMeta; 785 } 786 787 bool MatroskaExtractor::isLiveStreaming() const { 788 return mIsLiveStreaming; 789 } 790 791 static int bytesForSize(size_t size) { 792 // use at most 28 bits (4 times 7) 793 CHECK(size <= 0xfffffff); 794 795 if (size > 0x1fffff) { 796 return 4; 797 } else if (size > 0x3fff) { 798 return 3; 799 } else if (size > 0x7f) { 800 return 2; 801 } 802 return 1; 803 } 804 805 static void storeSize(uint8_t *data, size_t &idx, size_t size) { 806 int numBytes = bytesForSize(size); 807 idx += numBytes; 808 809 data += idx; 810 size_t next = 0; 811 while (numBytes--) { 812 *--data = (size & 0x7f) | next; 813 size >>= 7; 814 next = 0x80; 815 } 816 } 817 818 static void addESDSFromCodecPrivate( 819 const sp<MetaData> &meta, 820 bool isAudio, const void *priv, size_t privSize) { 821 822 int privSizeBytesRequired = bytesForSize(privSize); 823 int esdsSize2 = 14 + privSizeBytesRequired + privSize; 824 int esdsSize2BytesRequired = bytesForSize(esdsSize2); 825 int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2; 826 int esdsSize1BytesRequired = bytesForSize(esdsSize1); 827 size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1; 828 uint8_t *esds = new uint8_t[esdsSize]; 829 830 size_t idx = 0; 831 esds[idx++] = 0x03; 832 storeSize(esds, idx, esdsSize1); 833 esds[idx++] = 0x00; // ES_ID 834 esds[idx++] = 0x00; // ES_ID 835 esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 836 esds[idx++] = 0x04; 837 storeSize(esds, idx, esdsSize2); 838 esds[idx++] = isAudio ? 0x40 // Audio ISO/IEC 14496-3 839 : 0x20; // Visual ISO/IEC 14496-2 840 for (int i = 0; i < 12; i++) { 841 esds[idx++] = 0x00; 842 } 843 esds[idx++] = 0x05; 844 storeSize(esds, idx, privSize); 845 memcpy(esds + idx, priv, privSize); 846 847 meta->setData(kKeyESDS, 0, esds, esdsSize); 848 849 delete[] esds; 850 esds = NULL; 851 } 852 853 status_t addVorbisCodecInfo( 854 const sp<MetaData> &meta, 855 const void *_codecPrivate, size_t codecPrivateSize) { 856 // hexdump(_codecPrivate, codecPrivateSize); 857 858 if (codecPrivateSize < 1) { 859 return ERROR_MALFORMED; 860 } 861 862 const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 863 864 if (codecPrivate[0] != 0x02) { 865 return ERROR_MALFORMED; 866 } 867 868 // codecInfo starts with two lengths, len1 and len2, that are 869 // "Xiph-style-lacing encoded"... 870 871 size_t offset = 1; 872 size_t len1 = 0; 873 while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) { 874 if (len1 > (SIZE_MAX - 0xff)) { 875 return ERROR_MALFORMED; // would overflow 876 } 877 len1 += 0xff; 878 ++offset; 879 } 880 if (offset >= codecPrivateSize) { 881 return ERROR_MALFORMED; 882 } 883 if (len1 > (SIZE_MAX - codecPrivate[offset])) { 884 return ERROR_MALFORMED; // would overflow 885 } 886 len1 += codecPrivate[offset++]; 887 888 size_t len2 = 0; 889 while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) { 890 if (len2 > (SIZE_MAX - 0xff)) { 891 return ERROR_MALFORMED; // would overflow 892 } 893 len2 += 0xff; 894 ++offset; 895 } 896 if (offset >= codecPrivateSize) { 897 return ERROR_MALFORMED; 898 } 899 if (len2 > (SIZE_MAX - codecPrivate[offset])) { 900 return ERROR_MALFORMED; // would overflow 901 } 902 len2 += codecPrivate[offset++]; 903 904 if (len1 > SIZE_MAX - len2 || offset > SIZE_MAX - (len1 + len2) || 905 codecPrivateSize < offset + len1 + len2) { 906 return ERROR_MALFORMED; 907 } 908 909 if (codecPrivate[offset] != 0x01) { 910 return ERROR_MALFORMED; 911 } 912 meta->setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1); 913 914 offset += len1; 915 if (codecPrivate[offset] != 0x03) { 916 return ERROR_MALFORMED; 917 } 918 919 offset += len2; 920 if (codecPrivate[offset] != 0x05) { 921 return ERROR_MALFORMED; 922 } 923 924 meta->setData( 925 kKeyVorbisBooks, 0, &codecPrivate[offset], 926 codecPrivateSize - offset); 927 928 return OK; 929 } 930 931 void MatroskaExtractor::addTracks() { 932 const mkvparser::Tracks *tracks = mSegment->GetTracks(); 933 934 for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 935 const mkvparser::Track *track = tracks->GetTrackByIndex(index); 936 937 if (track == NULL) { 938 // Apparently this is currently valid (if unexpected) behaviour 939 // of the mkv parser lib. 940 continue; 941 } 942 943 const char *const codecID = track->GetCodecId(); 944 ALOGV("codec id = %s", codecID); 945 ALOGV("codec name = %s", track->GetCodecNameAsUTF8()); 946 947 if (codecID == NULL) { 948 ALOGW("unknown codecID is not supported."); 949 continue; 950 } 951 952 size_t codecPrivateSize; 953 const unsigned char *codecPrivate = 954 track->GetCodecPrivate(codecPrivateSize); 955 956 enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 957 958 sp<MetaData> meta = new MetaData; 959 960 status_t err = OK; 961 962 switch (track->GetType()) { 963 case VIDEO_TRACK: 964 { 965 const mkvparser::VideoTrack *vtrack = 966 static_cast<const mkvparser::VideoTrack *>(track); 967 968 if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 969 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 970 meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 971 } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { 972 if (codecPrivateSize > 0) { 973 meta->setCString( 974 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 975 addESDSFromCodecPrivate( 976 meta, false, codecPrivate, codecPrivateSize); 977 } else { 978 ALOGW("%s is detected, but does not have configuration.", 979 codecID); 980 continue; 981 } 982 } else if (!strcmp("V_VP8", codecID)) { 983 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); 984 } else if (!strcmp("V_VP9", codecID)) { 985 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); 986 } else { 987 ALOGW("%s is not supported.", codecID); 988 continue; 989 } 990 991 meta->setInt32(kKeyWidth, vtrack->GetWidth()); 992 meta->setInt32(kKeyHeight, vtrack->GetHeight()); 993 break; 994 } 995 996 case AUDIO_TRACK: 997 { 998 const mkvparser::AudioTrack *atrack = 999 static_cast<const mkvparser::AudioTrack *>(track); 1000 1001 if (!strcmp("A_AAC", codecID)) { 1002 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 1003 CHECK(codecPrivateSize >= 2); 1004 1005 addESDSFromCodecPrivate( 1006 meta, true, codecPrivate, codecPrivateSize); 1007 } else if (!strcmp("A_VORBIS", codecID)) { 1008 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 1009 1010 err = addVorbisCodecInfo( 1011 meta, codecPrivate, codecPrivateSize); 1012 } else if (!strcmp("A_OPUS", codecID)) { 1013 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_OPUS); 1014 meta->setData(kKeyOpusHeader, 0, codecPrivate, codecPrivateSize); 1015 meta->setInt64(kKeyOpusCodecDelay, track->GetCodecDelay()); 1016 meta->setInt64(kKeyOpusSeekPreRoll, track->GetSeekPreRoll()); 1017 mSeekPreRollNs = track->GetSeekPreRoll(); 1018 } else if (!strcmp("A_MPEG/L3", codecID)) { 1019 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 1020 } else { 1021 ALOGW("%s is not supported.", codecID); 1022 continue; 1023 } 1024 1025 meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 1026 meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 1027 break; 1028 } 1029 1030 default: 1031 continue; 1032 } 1033 1034 if (err != OK) { 1035 ALOGE("skipping track, codec specific data was malformed."); 1036 continue; 1037 } 1038 1039 long long durationNs = mSegment->GetDuration(); 1040 meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 1041 1042 mTracks.push(); 1043 TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 1044 trackInfo->mTrackNum = track->GetNumber(); 1045 trackInfo->mMeta = meta; 1046 trackInfo->mExtractor = this; 1047 } 1048 } 1049 1050 void MatroskaExtractor::findThumbnails() { 1051 for (size_t i = 0; i < mTracks.size(); ++i) { 1052 TrackInfo *info = &mTracks.editItemAt(i); 1053 1054 const char *mime; 1055 CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 1056 1057 if (strncasecmp(mime, "video/", 6)) { 1058 continue; 1059 } 1060 1061 BlockIterator iter(this, info->mTrackNum, i); 1062 int32_t j = 0; 1063 int64_t thumbnailTimeUs = 0; 1064 size_t maxBlockSize = 0; 1065 while (!iter.eos() && j < 20) { 1066 if (iter.block()->IsKey()) { 1067 ++j; 1068 1069 size_t blockSize = 0; 1070 for (int k = 0; k < iter.block()->GetFrameCount(); ++k) { 1071 blockSize += iter.block()->GetFrame(k).len; 1072 } 1073 1074 if (blockSize > maxBlockSize) { 1075 maxBlockSize = blockSize; 1076 thumbnailTimeUs = iter.blockTimeUs(); 1077 } 1078 } 1079 iter.advance(); 1080 } 1081 info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 1082 } 1083 } 1084 1085 sp<MetaData> MatroskaExtractor::getMetaData() { 1086 sp<MetaData> meta = new MetaData; 1087 1088 meta->setCString( 1089 kKeyMIMEType, 1090 mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA); 1091 1092 return meta; 1093 } 1094 1095 uint32_t MatroskaExtractor::flags() const { 1096 uint32_t x = CAN_PAUSE; 1097 if (!isLiveStreaming()) { 1098 x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK; 1099 } 1100 1101 return x; 1102 } 1103 1104 bool SniffMatroska( 1105 const sp<DataSource> &source, String8 *mimeType, float *confidence, 1106 sp<AMessage> *) { 1107 DataSourceReader reader(source); 1108 mkvparser::EBMLHeader ebmlHeader; 1109 long long pos; 1110 if (ebmlHeader.Parse(&reader, pos) < 0) { 1111 return false; 1112 } 1113 1114 mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 1115 *confidence = 0.6; 1116 1117 return true; 1118 } 1119 1120 } // namespace android 1121