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