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