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