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