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