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