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