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 "mkvparser.hpp"
     24 
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/foundation/hexdump.h>
     27 #include <media/stagefright/DataSource.h>
     28 #include <media/stagefright/MediaBuffer.h>
     29 #include <media/stagefright/MediaDefs.h>
     30 #include <media/stagefright/MediaErrors.h>
     31 #include <media/stagefright/MediaSource.h>
     32 #include <media/stagefright/MetaData.h>
     33 #include <media/stagefright/Utils.h>
     34 #include <utils/String8.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);
     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     unsigned long mTrackNum;
    107 
    108     const mkvparser::Cluster *mCluster;
    109     const mkvparser::BlockEntry *mBlockEntry;
    110     long mBlockEntryIndex;
    111 
    112     void advance_l();
    113 
    114     BlockIterator(const BlockIterator &);
    115     BlockIterator &operator=(const BlockIterator &);
    116 };
    117 
    118 struct MatroskaSource : public MediaSource {
    119     MatroskaSource(
    120             const sp<MatroskaExtractor> &extractor, size_t index);
    121 
    122     virtual status_t start(MetaData *params);
    123     virtual status_t stop();
    124 
    125     virtual sp<MetaData> getFormat();
    126 
    127     virtual status_t read(
    128             MediaBuffer **buffer, const ReadOptions *options);
    129 
    130 protected:
    131     virtual ~MatroskaSource();
    132 
    133 private:
    134     enum Type {
    135         AVC,
    136         AAC,
    137         OTHER
    138     };
    139 
    140     sp<MatroskaExtractor> mExtractor;
    141     size_t mTrackIndex;
    142     Type mType;
    143     bool mIsAudio;
    144     BlockIterator mBlockIter;
    145     size_t mNALSizeLen;  // for type AVC
    146 
    147     List<MediaBuffer *> mPendingFrames;
    148 
    149     status_t advance();
    150 
    151     status_t readBlock();
    152     void clearPendingFrames();
    153 
    154     MatroskaSource(const MatroskaSource &);
    155     MatroskaSource &operator=(const MatroskaSource &);
    156 };
    157 
    158 MatroskaSource::MatroskaSource(
    159         const sp<MatroskaExtractor> &extractor, size_t index)
    160     : mExtractor(extractor),
    161       mTrackIndex(index),
    162       mType(OTHER),
    163       mIsAudio(false),
    164       mBlockIter(mExtractor.get(),
    165                  mExtractor->mTracks.itemAt(index).mTrackNum),
    166       mNALSizeLen(0) {
    167     sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
    168 
    169     const char *mime;
    170     CHECK(meta->findCString(kKeyMIMEType, &mime));
    171 
    172     mIsAudio = !strncasecmp("audio/", mime, 6);
    173 
    174     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
    175         mType = AVC;
    176 
    177         uint32_t dummy;
    178         const uint8_t *avcc;
    179         size_t avccSize;
    180         CHECK(meta->findData(
    181                     kKeyAVCC, &dummy, (const void **)&avcc, &avccSize));
    182 
    183         CHECK_GE(avccSize, 5u);
    184 
    185         mNALSizeLen = 1 + (avcc[4] & 3);
    186         ALOGV("mNALSizeLen = %d", mNALSizeLen);
    187     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
    188         mType = AAC;
    189     }
    190 }
    191 
    192 MatroskaSource::~MatroskaSource() {
    193     clearPendingFrames();
    194 }
    195 
    196 status_t MatroskaSource::start(MetaData *params) {
    197     mBlockIter.reset();
    198 
    199     return OK;
    200 }
    201 
    202 status_t MatroskaSource::stop() {
    203     clearPendingFrames();
    204 
    205     return OK;
    206 }
    207 
    208 sp<MetaData> MatroskaSource::getFormat() {
    209     return mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
    210 }
    211 
    212 ////////////////////////////////////////////////////////////////////////////////
    213 
    214 BlockIterator::BlockIterator(
    215         MatroskaExtractor *extractor, unsigned long trackNum)
    216     : mExtractor(extractor),
    217       mTrackNum(trackNum),
    218       mCluster(NULL),
    219       mBlockEntry(NULL),
    220       mBlockEntryIndex(0) {
    221     reset();
    222 }
    223 
    224 bool BlockIterator::eos() const {
    225     return mCluster == NULL || mCluster->EOS();
    226 }
    227 
    228 void BlockIterator::advance() {
    229     Mutex::Autolock autoLock(mExtractor->mLock);
    230     advance_l();
    231 }
    232 
    233 void BlockIterator::advance_l() {
    234     for (;;) {
    235         long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
    236         ALOGV("GetEntry returned %ld", res);
    237 
    238         long long pos;
    239         long len;
    240         if (res < 0) {
    241             // Need to parse this cluster some more
    242 
    243             CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);
    244 
    245             res = mCluster->Parse(pos, len);
    246             ALOGV("Parse returned %ld", res);
    247 
    248             if (res < 0) {
    249                 // I/O error
    250 
    251                 ALOGE("Cluster::Parse returned result %ld", res);
    252 
    253                 mCluster = NULL;
    254                 break;
    255             }
    256 
    257             continue;
    258         } else if (res == 0) {
    259             // We're done with this cluster
    260 
    261             const mkvparser::Cluster *nextCluster;
    262             res = mExtractor->mSegment->ParseNext(
    263                     mCluster, nextCluster, pos, len);
    264             ALOGV("ParseNext returned %ld", res);
    265 
    266             if (res > 0) {
    267                 // EOF
    268 
    269                 mCluster = NULL;
    270                 break;
    271             }
    272 
    273             CHECK_EQ(res, 0);
    274             CHECK(nextCluster != NULL);
    275             CHECK(!nextCluster->EOS());
    276 
    277             mCluster = nextCluster;
    278 
    279             res = mCluster->Parse(pos, len);
    280             ALOGV("Parse (2) returned %ld", res);
    281             CHECK_GE(res, 0);
    282 
    283             mBlockEntryIndex = 0;
    284             continue;
    285         }
    286 
    287         CHECK(mBlockEntry != NULL);
    288         CHECK(mBlockEntry->GetBlock() != NULL);
    289         ++mBlockEntryIndex;
    290 
    291         if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
    292             break;
    293         }
    294     }
    295 }
    296 
    297 void BlockIterator::reset() {
    298     Mutex::Autolock autoLock(mExtractor->mLock);
    299 
    300     mCluster = mExtractor->mSegment->GetFirst();
    301     mBlockEntry = NULL;
    302     mBlockEntryIndex = 0;
    303 
    304     do {
    305         advance_l();
    306     } while (!eos() && block()->GetTrackNumber() != mTrackNum);
    307 }
    308 
    309 void BlockIterator::seek(
    310         int64_t seekTimeUs, bool isAudio,
    311         int64_t *actualFrameTimeUs) {
    312     Mutex::Autolock autoLock(mExtractor->mLock);
    313 
    314     *actualFrameTimeUs = -1ll;
    315 
    316     const int64_t seekTimeNs = seekTimeUs * 1000ll;
    317 
    318     mkvparser::Segment* const pSegment = mExtractor->mSegment;
    319 
    320     // Special case the 0 seek to avoid loading Cues when the application
    321     // extraneously seeks to 0 before playing.
    322     if (seekTimeNs <= 0) {
    323         ALOGV("Seek to beginning: %lld", seekTimeUs);
    324         mCluster = pSegment->GetFirst();
    325         mBlockEntryIndex = 0;
    326         do {
    327             advance_l();
    328         } while (!eos() && block()->GetTrackNumber() != mTrackNum);
    329         return;
    330     }
    331 
    332     ALOGV("Seeking to: %lld", seekTimeUs);
    333 
    334     // If the Cues have not been located then find them.
    335     const mkvparser::Cues* pCues = pSegment->GetCues();
    336     const mkvparser::SeekHead* pSH = pSegment->GetSeekHead();
    337     if (!pCues && pSH) {
    338         const size_t count = pSH->GetCount();
    339         const mkvparser::SeekHead::Entry* pEntry;
    340         ALOGV("No Cues yet");
    341 
    342         for (size_t index = 0; index < count; index++) {
    343             pEntry = pSH->GetEntry(index);
    344 
    345             if (pEntry->id == 0x0C53BB6B) { // Cues ID
    346                 long len; long long pos;
    347                 pSegment->ParseCues(pEntry->pos, pos, len);
    348                 pCues = pSegment->GetCues();
    349                 ALOGV("Cues found");
    350                 break;
    351             }
    352         }
    353 
    354         if (!pCues) {
    355             ALOGE("No Cues in file");
    356             return;
    357         }
    358     }
    359     else if (!pSH) {
    360         ALOGE("No SeekHead");
    361         return;
    362     }
    363 
    364     const mkvparser::CuePoint* pCP;
    365     while (!pCues->DoneParsing()) {
    366         pCues->LoadCuePoint();
    367         pCP = pCues->GetLast();
    368 
    369         if (pCP->GetTime(pSegment) >= seekTimeNs) {
    370             ALOGV("Parsed past relevant Cue");
    371             break;
    372         }
    373     }
    374 
    375     // The Cue index is built around video keyframes
    376     mkvparser::Tracks const *pTracks = pSegment->GetTracks();
    377     const mkvparser::Track *pTrack = NULL;
    378     for (size_t index = 0; index < pTracks->GetTracksCount(); ++index) {
    379         pTrack = pTracks->GetTrackByIndex(index);
    380         if (pTrack && pTrack->GetType() == 1) { // VIDEO_TRACK
    381             ALOGV("Video track located at %d", index);
    382             break;
    383         }
    384     }
    385 
    386     // Always *search* based on the video track, but finalize based on mTrackNum
    387     const mkvparser::CuePoint::TrackPosition* pTP;
    388     if (pTrack && pTrack->GetType() == 1) {
    389         pCues->Find(seekTimeNs, pTrack, pCP, pTP);
    390     } else {
    391         ALOGE("Did not locate the video track for seeking");
    392         return;
    393     }
    394 
    395     mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos);
    396 
    397     CHECK(mCluster);
    398     CHECK(!mCluster->EOS());
    399 
    400     // mBlockEntryIndex starts at 0 but m_block starts at 1
    401     CHECK_GT(pTP->m_block, 0);
    402     mBlockEntryIndex = pTP->m_block - 1;
    403 
    404     for (;;) {
    405         advance_l();
    406 
    407         if (eos()) break;
    408 
    409         if (isAudio || block()->IsKey()) {
    410             // Accept the first key frame
    411             *actualFrameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL;
    412             ALOGV("Requested seek point: %lld actual: %lld",
    413                   seekTimeUs, actualFrameTimeUs);
    414             break;
    415         }
    416     }
    417 }
    418 
    419 const mkvparser::Block *BlockIterator::block() const {
    420     CHECK(!eos());
    421 
    422     return mBlockEntry->GetBlock();
    423 }
    424 
    425 int64_t BlockIterator::blockTimeUs() const {
    426     return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
    427 }
    428 
    429 ////////////////////////////////////////////////////////////////////////////////
    430 
    431 static unsigned U24_AT(const uint8_t *ptr) {
    432     return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
    433 }
    434 
    435 static size_t clz(uint8_t x) {
    436     size_t numLeadingZeroes = 0;
    437 
    438     while (!(x & 0x80)) {
    439         ++numLeadingZeroes;
    440         x = x << 1;
    441     }
    442 
    443     return numLeadingZeroes;
    444 }
    445 
    446 void MatroskaSource::clearPendingFrames() {
    447     while (!mPendingFrames.empty()) {
    448         MediaBuffer *frame = *mPendingFrames.begin();
    449         mPendingFrames.erase(mPendingFrames.begin());
    450 
    451         frame->release();
    452         frame = NULL;
    453     }
    454 }
    455 
    456 status_t MatroskaSource::readBlock() {
    457     CHECK(mPendingFrames.empty());
    458 
    459     if (mBlockIter.eos()) {
    460         return ERROR_END_OF_STREAM;
    461     }
    462 
    463     const mkvparser::Block *block = mBlockIter.block();
    464 
    465     int64_t timeUs = mBlockIter.blockTimeUs();
    466 
    467     for (int i = 0; i < block->GetFrameCount(); ++i) {
    468         const mkvparser::Block::Frame &frame = block->GetFrame(i);
    469 
    470         MediaBuffer *mbuf = new MediaBuffer(frame.len);
    471         mbuf->meta_data()->setInt64(kKeyTime, timeUs);
    472         mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
    473 
    474         long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data());
    475         if (n != 0) {
    476             mPendingFrames.clear();
    477 
    478             mBlockIter.advance();
    479             return ERROR_IO;
    480         }
    481 
    482         mPendingFrames.push_back(mbuf);
    483     }
    484 
    485     mBlockIter.advance();
    486 
    487     return OK;
    488 }
    489 
    490 status_t MatroskaSource::read(
    491         MediaBuffer **out, const ReadOptions *options) {
    492     *out = NULL;
    493 
    494     int64_t targetSampleTimeUs = -1ll;
    495 
    496     int64_t seekTimeUs;
    497     ReadOptions::SeekMode mode;
    498     if (options && options->getSeekTo(&seekTimeUs, &mode)
    499             && !mExtractor->isLiveStreaming()) {
    500         clearPendingFrames();
    501 
    502         // The audio we want is located by using the Cues to seek the video
    503         // stream to find the target Cluster then iterating to finalize for
    504         // audio.
    505         int64_t actualFrameTimeUs;
    506         mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs);
    507 
    508         if (mode == ReadOptions::SEEK_CLOSEST) {
    509             targetSampleTimeUs = actualFrameTimeUs;
    510         }
    511     }
    512 
    513     while (mPendingFrames.empty()) {
    514         status_t err = readBlock();
    515 
    516         if (err != OK) {
    517             clearPendingFrames();
    518 
    519             return err;
    520         }
    521     }
    522 
    523     MediaBuffer *frame = *mPendingFrames.begin();
    524     mPendingFrames.erase(mPendingFrames.begin());
    525 
    526     if (mType != AVC) {
    527         if (targetSampleTimeUs >= 0ll) {
    528             frame->meta_data()->setInt64(
    529                     kKeyTargetTime, targetSampleTimeUs);
    530         }
    531 
    532         *out = frame;
    533 
    534         return OK;
    535     }
    536 
    537     // Each input frame contains one or more NAL fragments, each fragment
    538     // is prefixed by mNALSizeLen bytes giving the fragment length,
    539     // followed by a corresponding number of bytes containing the fragment.
    540     // We output all these fragments into a single large buffer separated
    541     // by startcodes (0x00 0x00 0x00 0x01).
    542 
    543     const uint8_t *srcPtr =
    544         (const uint8_t *)frame->data() + frame->range_offset();
    545 
    546     size_t srcSize = frame->range_length();
    547 
    548     size_t dstSize = 0;
    549     MediaBuffer *buffer = NULL;
    550     uint8_t *dstPtr = NULL;
    551 
    552     for (int32_t pass = 0; pass < 2; ++pass) {
    553         size_t srcOffset = 0;
    554         size_t dstOffset = 0;
    555         while (srcOffset + mNALSizeLen <= srcSize) {
    556             size_t NALsize;
    557             switch (mNALSizeLen) {
    558                 case 1: NALsize = srcPtr[srcOffset]; break;
    559                 case 2: NALsize = U16_AT(srcPtr + srcOffset); break;
    560                 case 3: NALsize = U24_AT(srcPtr + srcOffset); break;
    561                 case 4: NALsize = U32_AT(srcPtr + srcOffset); break;
    562                 default:
    563                     TRESPASS();
    564             }
    565 
    566             if (srcOffset + mNALSizeLen + NALsize > srcSize) {
    567                 break;
    568             }
    569 
    570             if (pass == 1) {
    571                 memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4);
    572 
    573                 memcpy(&dstPtr[dstOffset + 4],
    574                        &srcPtr[srcOffset + mNALSizeLen],
    575                        NALsize);
    576             }
    577 
    578             dstOffset += 4;  // 0x00 00 00 01
    579             dstOffset += NALsize;
    580 
    581             srcOffset += mNALSizeLen + NALsize;
    582         }
    583 
    584         if (srcOffset < srcSize) {
    585             // There were trailing bytes or not enough data to complete
    586             // a fragment.
    587 
    588             frame->release();
    589             frame = NULL;
    590 
    591             return ERROR_MALFORMED;
    592         }
    593 
    594         if (pass == 0) {
    595             dstSize = dstOffset;
    596 
    597             buffer = new MediaBuffer(dstSize);
    598 
    599             int64_t timeUs;
    600             CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs));
    601             int32_t isSync;
    602             CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync));
    603 
    604             buffer->meta_data()->setInt64(kKeyTime, timeUs);
    605             buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
    606 
    607             dstPtr = (uint8_t *)buffer->data();
    608         }
    609     }
    610 
    611     frame->release();
    612     frame = NULL;
    613 
    614     if (targetSampleTimeUs >= 0ll) {
    615         buffer->meta_data()->setInt64(
    616                 kKeyTargetTime, targetSampleTimeUs);
    617     }
    618 
    619     *out = buffer;
    620 
    621     return OK;
    622 }
    623 
    624 ////////////////////////////////////////////////////////////////////////////////
    625 
    626 MatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
    627     : mDataSource(source),
    628       mReader(new DataSourceReader(mDataSource)),
    629       mSegment(NULL),
    630       mExtractedThumbnails(false),
    631       mIsWebm(false) {
    632     off64_t size;
    633     mIsLiveStreaming =
    634         (mDataSource->flags()
    635             & (DataSource::kWantsPrefetching
    636                 | DataSource::kIsCachingDataSource))
    637         && mDataSource->getSize(&size) != OK;
    638 
    639     mkvparser::EBMLHeader ebmlHeader;
    640     long long pos;
    641     if (ebmlHeader.Parse(mReader, pos) < 0) {
    642         return;
    643     }
    644 
    645     if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) {
    646         mIsWebm = true;
    647     }
    648 
    649     long long ret =
    650         mkvparser::Segment::CreateInstance(mReader, pos, mSegment);
    651 
    652     if (ret) {
    653         CHECK(mSegment == NULL);
    654         return;
    655     }
    656 
    657     ret = mSegment->ParseHeaders();
    658     CHECK_EQ(ret, 0);
    659 
    660     long len;
    661     ret = mSegment->LoadCluster(pos, len);
    662     CHECK_EQ(ret, 0);
    663 
    664     if (ret < 0) {
    665         delete mSegment;
    666         mSegment = NULL;
    667         return;
    668     }
    669 
    670 #if 0
    671     const mkvparser::SegmentInfo *info = mSegment->GetInfo();
    672     ALOGI("muxing app: %s, writing app: %s",
    673          info->GetMuxingAppAsUTF8(),
    674          info->GetWritingAppAsUTF8());
    675 #endif
    676 
    677     addTracks();
    678 }
    679 
    680 MatroskaExtractor::~MatroskaExtractor() {
    681     delete mSegment;
    682     mSegment = NULL;
    683 
    684     delete mReader;
    685     mReader = NULL;
    686 }
    687 
    688 size_t MatroskaExtractor::countTracks() {
    689     return mTracks.size();
    690 }
    691 
    692 sp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
    693     if (index >= mTracks.size()) {
    694         return NULL;
    695     }
    696 
    697     return new MatroskaSource(this, index);
    698 }
    699 
    700 sp<MetaData> MatroskaExtractor::getTrackMetaData(
    701         size_t index, uint32_t flags) {
    702     if (index >= mTracks.size()) {
    703         return NULL;
    704     }
    705 
    706     if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
    707             && !isLiveStreaming()) {
    708         findThumbnails();
    709         mExtractedThumbnails = true;
    710     }
    711 
    712     return mTracks.itemAt(index).mMeta;
    713 }
    714 
    715 bool MatroskaExtractor::isLiveStreaming() const {
    716     return mIsLiveStreaming;
    717 }
    718 
    719 static void addESDSFromCodecPrivate(
    720         const sp<MetaData> &meta,
    721         bool isAudio, const void *priv, size_t privSize) {
    722     static const uint8_t kStaticESDS[] = {
    723         0x03, 22,
    724         0x00, 0x00,     // ES_ID
    725         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
    726 
    727         0x04, 17,
    728         0x40,           // ObjectTypeIndication
    729         0x00, 0x00, 0x00, 0x00,
    730         0x00, 0x00, 0x00, 0x00,
    731         0x00, 0x00, 0x00, 0x00,
    732 
    733         0x05,
    734         // CodecSpecificInfo (with size prefix) follows
    735     };
    736 
    737     // Make sure all sizes can be coded in a single byte.
    738     CHECK(privSize + 22 - 2 < 128);
    739     size_t esdsSize = sizeof(kStaticESDS) + privSize + 1;
    740     uint8_t *esds = new uint8_t[esdsSize];
    741     memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
    742     uint8_t *ptr = esds + sizeof(kStaticESDS);
    743     *ptr++ = privSize;
    744     memcpy(ptr, priv, privSize);
    745 
    746     // Increment by codecPrivateSize less 2 bytes that are accounted for
    747     // already in lengths of 22/17
    748     esds[1] += privSize - 2;
    749     esds[6] += privSize - 2;
    750 
    751     // Set ObjectTypeIndication.
    752     esds[7] = isAudio ? 0x40   // Audio ISO/IEC 14496-3
    753                       : 0x20;  // Visual ISO/IEC 14496-2
    754 
    755     meta->setData(kKeyESDS, 0, esds, esdsSize);
    756 
    757     delete[] esds;
    758     esds = NULL;
    759 }
    760 
    761 void addVorbisCodecInfo(
    762         const sp<MetaData> &meta,
    763         const void *_codecPrivate, size_t codecPrivateSize) {
    764     // printf("vorbis private data follows:\n");
    765     // hexdump(_codecPrivate, codecPrivateSize);
    766 
    767     CHECK(codecPrivateSize >= 3);
    768 
    769     const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
    770     CHECK(codecPrivate[0] == 0x02);
    771 
    772     size_t len1 = codecPrivate[1];
    773     size_t len2 = codecPrivate[2];
    774 
    775     CHECK(codecPrivateSize > 3 + len1 + len2);
    776 
    777     CHECK(codecPrivate[3] == 0x01);
    778     meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
    779 
    780     CHECK(codecPrivate[len1 + 3] == 0x03);
    781 
    782     CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
    783     meta->setData(
    784             kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
    785             codecPrivateSize - len1 - len2 - 3);
    786 }
    787 
    788 void MatroskaExtractor::addTracks() {
    789     const mkvparser::Tracks *tracks = mSegment->GetTracks();
    790 
    791     for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
    792         const mkvparser::Track *track = tracks->GetTrackByIndex(index);
    793 
    794         if (track == NULL) {
    795             // Apparently this is currently valid (if unexpected) behaviour
    796             // of the mkv parser lib.
    797             continue;
    798         }
    799 
    800         const char *const codecID = track->GetCodecId();
    801         ALOGV("codec id = %s", codecID);
    802         ALOGV("codec name = %s", track->GetCodecNameAsUTF8());
    803 
    804         size_t codecPrivateSize;
    805         const unsigned char *codecPrivate =
    806             track->GetCodecPrivate(codecPrivateSize);
    807 
    808         enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
    809 
    810         sp<MetaData> meta = new MetaData;
    811 
    812         switch (track->GetType()) {
    813             case VIDEO_TRACK:
    814             {
    815                 const mkvparser::VideoTrack *vtrack =
    816                     static_cast<const mkvparser::VideoTrack *>(track);
    817 
    818                 if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
    819                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
    820                     meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
    821                 } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
    822                     if (codecPrivateSize > 0) {
    823                         meta->setCString(
    824                                 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
    825                         addESDSFromCodecPrivate(
    826                                 meta, false, codecPrivate, codecPrivateSize);
    827                     } else {
    828                         ALOGW("%s is detected, but does not have configuration.",
    829                                 codecID);
    830                         continue;
    831                     }
    832                 } else if (!strcmp("V_VP8", codecID)) {
    833                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX);
    834                 } else {
    835                     ALOGW("%s is not supported.", codecID);
    836                     continue;
    837                 }
    838 
    839                 meta->setInt32(kKeyWidth, vtrack->GetWidth());
    840                 meta->setInt32(kKeyHeight, vtrack->GetHeight());
    841                 break;
    842             }
    843 
    844             case AUDIO_TRACK:
    845             {
    846                 const mkvparser::AudioTrack *atrack =
    847                     static_cast<const mkvparser::AudioTrack *>(track);
    848 
    849                 if (!strcmp("A_AAC", codecID)) {
    850                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
    851                     CHECK(codecPrivateSize >= 2);
    852 
    853                     addESDSFromCodecPrivate(
    854                             meta, true, codecPrivate, codecPrivateSize);
    855                 } else if (!strcmp("A_VORBIS", codecID)) {
    856                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
    857 
    858                     addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
    859                 } else if (!strcmp("A_MPEG/L3", codecID)) {
    860                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
    861                 } else {
    862                     ALOGW("%s is not supported.", codecID);
    863                     continue;
    864                 }
    865 
    866                 meta->setInt32(kKeySampleRate, atrack->GetSamplingRate());
    867                 meta->setInt32(kKeyChannelCount, atrack->GetChannels());
    868                 break;
    869             }
    870 
    871             default:
    872                 continue;
    873         }
    874 
    875         long long durationNs = mSegment->GetDuration();
    876         meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);
    877 
    878         mTracks.push();
    879         TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1);
    880         trackInfo->mTrackNum = track->GetNumber();
    881         trackInfo->mMeta = meta;
    882     }
    883 }
    884 
    885 void MatroskaExtractor::findThumbnails() {
    886     for (size_t i = 0; i < mTracks.size(); ++i) {
    887         TrackInfo *info = &mTracks.editItemAt(i);
    888 
    889         const char *mime;
    890         CHECK(info->mMeta->findCString(kKeyMIMEType, &mime));
    891 
    892         if (strncasecmp(mime, "video/", 6)) {
    893             continue;
    894         }
    895 
    896         BlockIterator iter(this, info->mTrackNum);
    897         int32_t i = 0;
    898         int64_t thumbnailTimeUs = 0;
    899         size_t maxBlockSize = 0;
    900         while (!iter.eos() && i < 20) {
    901             if (iter.block()->IsKey()) {
    902                 ++i;
    903 
    904                 size_t blockSize = 0;
    905                 for (int i = 0; i < iter.block()->GetFrameCount(); ++i) {
    906                     blockSize += iter.block()->GetFrame(i).len;
    907                 }
    908 
    909                 if (blockSize > maxBlockSize) {
    910                     maxBlockSize = blockSize;
    911                     thumbnailTimeUs = iter.blockTimeUs();
    912                 }
    913             }
    914             iter.advance();
    915         }
    916         info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
    917     }
    918 }
    919 
    920 sp<MetaData> MatroskaExtractor::getMetaData() {
    921     sp<MetaData> meta = new MetaData;
    922 
    923     meta->setCString(
    924             kKeyMIMEType,
    925             mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA);
    926 
    927     return meta;
    928 }
    929 
    930 uint32_t MatroskaExtractor::flags() const {
    931     uint32_t x = CAN_PAUSE;
    932     if (!isLiveStreaming()) {
    933         x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
    934     }
    935 
    936     return x;
    937 }
    938 
    939 bool SniffMatroska(
    940         const sp<DataSource> &source, String8 *mimeType, float *confidence,
    941         sp<AMessage> *) {
    942     DataSourceReader reader(source);
    943     mkvparser::EBMLHeader ebmlHeader;
    944     long long pos;
    945     if (ebmlHeader.Parse(&reader, pos) < 0) {
    946         return false;
    947     }
    948 
    949     mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA);
    950     *confidence = 0.6;
    951 
    952     return true;
    953 }
    954 
    955 }  // namespace android
    956