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 #include "common/webmids.h"
24 
25 #include <media/DataSourceBase.h>
26 #include <media/ExtractorUtils.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/MediaDefs.h>
34 #include <media/stagefright/MediaErrors.h>
35 #include <media/stagefright/MetaDataUtils.h>
36 #include <media/stagefright/foundation/avc_utils.h>
37 #include <utils/String8.h>
38 
39 #include <arpa/inet.h>
40 #include <inttypes.h>
41 #include <vector>
42 
43 namespace android {
44 
45 struct DataSourceBaseReader : public mkvparser::IMkvReader {
DataSourceBaseReaderandroid::DataSourceBaseReader46     explicit DataSourceBaseReader(DataSourceHelper *source)
47         : mSource(source) {
48     }
49 
Readandroid::DataSourceBaseReader50     virtual int Read(long long position, long length, unsigned char* buffer) {
51         CHECK(position >= 0);
52         CHECK(length >= 0);
53 
54         if (length == 0) {
55             return 0;
56         }
57 
58         ssize_t n = mSource->readAt(position, buffer, length);
59 
60         if (n <= 0) {
61             return -1;
62         }
63 
64         return 0;
65     }
66 
Lengthandroid::DataSourceBaseReader67     virtual int Length(long long* total, long long* available) {
68         off64_t size;
69         if (mSource->getSize(&size) != OK) {
70             if (total) {
71                 *total = -1;
72             }
73             if (available) {
74                 *available = (long long)((1ull << 63) - 1);
75             }
76 
77             return 0;
78         }
79 
80         if (total) {
81             *total = size;
82         }
83 
84         if (available) {
85             *available = size;
86         }
87 
88         return 0;
89     }
90 
91 private:
92     DataSourceHelper *mSource;
93 
94     DataSourceBaseReader(const DataSourceBaseReader &);
95     DataSourceBaseReader &operator=(const DataSourceBaseReader &);
96 };
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 
100 struct BlockIterator {
101     BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index);
102 
103     bool eos() const;
104 
105     void advance();
106     void reset();
107 
108     void seek(
109             int64_t seekTimeUs, bool isAudio,
110             int64_t *actualFrameTimeUs);
111 
112     const mkvparser::Block *block() const;
113     int64_t blockTimeUs() const;
114 
115 private:
116     MatroskaExtractor *mExtractor;
117     long long mTrackNum;
118     unsigned long mIndex;
119 
120     const mkvparser::Cluster *mCluster;
121     const mkvparser::BlockEntry *mBlockEntry;
122     long mBlockEntryIndex;
123 
124     unsigned long mTrackType;
125     void seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs);
126 
127     void advance_l();
128 
129     BlockIterator(const BlockIterator &);
130     BlockIterator &operator=(const BlockIterator &);
131 };
132 
133 struct MatroskaSource : public MediaTrackHelper {
134     MatroskaSource(MatroskaExtractor *extractor, size_t index);
135 
136     virtual media_status_t start();
137     virtual media_status_t stop();
138 
139     virtual media_status_t getFormat(AMediaFormat *);
140 
141     virtual media_status_t read(
142             MediaBufferHelper **buffer, const ReadOptions *options);
143 
144 protected:
145     virtual ~MatroskaSource();
146 
147 private:
148     enum Type {
149         AVC,
150         AAC,
151         HEVC,
152         MP3,
153         PCM,
154         VORBIS,
155         OTHER
156     };
157 
158     MatroskaExtractor *mExtractor;
159     size_t mTrackIndex;
160     Type mType;
161     bool mIsAudio;
162     BlockIterator mBlockIter;
163     ssize_t mNALSizeLen;  // for type AVC or HEVC
164 
165     List<MediaBufferHelper *> mPendingFrames;
166 
167     int64_t mCurrentTS; // add for mp3
168     uint32_t mMP3Header;
169 
170     media_status_t findMP3Header(uint32_t * header,
171         const uint8_t *dataSource, int length, int *outStartPos);
172     media_status_t mp3FrameRead(
173             MediaBufferHelper **out, const ReadOptions *options,
174             int64_t targetSampleTimeUs);
175 
176     status_t advance();
177 
178     status_t setWebmBlockCryptoInfo(MediaBufferHelper *mbuf);
179     media_status_t readBlock();
180     void clearPendingFrames();
181 
182     MatroskaSource(const MatroskaSource &);
183     MatroskaSource &operator=(const MatroskaSource &);
184 };
185 
getTrack() const186 const mkvparser::Track* MatroskaExtractor::TrackInfo::getTrack() const {
187     return mExtractor->mSegment->GetTracks()->GetTrackByNumber(mTrackNum);
188 }
189 
190 // This function does exactly the same as mkvparser::Cues::Find, except that it
191 // searches in our own track based vectors. We should not need this once mkvparser
192 // adds the same functionality.
find(long long timeNs) const193 const mkvparser::CuePoint::TrackPosition *MatroskaExtractor::TrackInfo::find(
194         long long timeNs) const {
195     ALOGV("mCuePoints.size %zu", mCuePoints.size());
196     if (mCuePoints.empty()) {
197         return NULL;
198     }
199 
200     const mkvparser::CuePoint* cp = mCuePoints.itemAt(0);
201     const mkvparser::Track* track = getTrack();
202     if (timeNs <= cp->GetTime(mExtractor->mSegment)) {
203         return cp->Find(track);
204     }
205 
206     // Binary searches through relevant cues; assumes cues are ordered by timecode.
207     // If we do detect out-of-order cues, return NULL.
208     size_t lo = 0;
209     size_t hi = mCuePoints.size();
210     while (lo < hi) {
211         const size_t mid = lo + (hi - lo) / 2;
212         const mkvparser::CuePoint* const midCp = mCuePoints.itemAt(mid);
213         const long long cueTimeNs = midCp->GetTime(mExtractor->mSegment);
214         if (cueTimeNs <= timeNs) {
215             lo = mid + 1;
216         } else {
217             hi = mid;
218         }
219     }
220 
221     if (lo == 0) {
222         return NULL;
223     }
224 
225     cp = mCuePoints.itemAt(lo - 1);
226     if (cp->GetTime(mExtractor->mSegment) > timeNs) {
227         return NULL;
228     }
229 
230     return cp->Find(track);
231 }
232 
MatroskaSource(MatroskaExtractor * extractor,size_t index)233 MatroskaSource::MatroskaSource(
234         MatroskaExtractor *extractor, size_t index)
235     : mExtractor(extractor),
236       mTrackIndex(index),
237       mType(OTHER),
238       mIsAudio(false),
239       mBlockIter(mExtractor,
240                  mExtractor->mTracks.itemAt(index).mTrackNum,
241                  index),
242       mNALSizeLen(-1),
243       mCurrentTS(0),
244       mMP3Header(0) {
245     MatroskaExtractor::TrackInfo &trackInfo = mExtractor->mTracks.editItemAt(index);
246     AMediaFormat *meta = trackInfo.mMeta;
247 
248     const char *mime;
249     CHECK(AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mime));
250 
251     mIsAudio = !strncasecmp("audio/", mime, 6);
252 
253     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
254         mType = AVC;
255 
256         int32_t nalSizeLen = trackInfo.mNalLengthSize;
257         if (nalSizeLen >= 0 && nalSizeLen <= 4) {
258             mNALSizeLen = nalSizeLen;
259         } else {
260             ALOGE("No AVC mNALSizeLen");
261         }
262     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
263         mType = HEVC;
264 
265         int32_t nalSizeLen = trackInfo.mNalLengthSize;
266         if (nalSizeLen >= 0 && nalSizeLen <= 4) {
267             mNALSizeLen = nalSizeLen;
268         } else {
269             ALOGE("No HEVC mNALSizeLen");
270         }
271     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
272         mType = AAC;
273     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
274         mType = MP3;
275     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
276         mType = PCM;
277     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
278         mType = VORBIS;
279     }
280 }
281 
~MatroskaSource()282 MatroskaSource::~MatroskaSource() {
283     clearPendingFrames();
284 }
285 
start()286 media_status_t MatroskaSource::start() {
287     if (mType == AVC && mNALSizeLen < 0) {
288         return AMEDIA_ERROR_MALFORMED;
289     }
290 
291     // allocate one small initial buffer, but leave plenty of room to grow
292     mBufferGroup->init(1 /* number of buffers */, 1024 /* buffer size */, 64 /* growth limit */);
293     mBlockIter.reset();
294 
295     if (mType == MP3 && mMP3Header == 0) {
296         int start = -1;
297         media_status_t err = findMP3Header(&mMP3Header, NULL, 0, &start);
298         if (err != OK) {
299             ALOGE("No mp3 header found");
300             clearPendingFrames();
301             return err;
302         }
303     }
304 
305     return AMEDIA_OK;
306 }
307 
stop()308 media_status_t MatroskaSource::stop() {
309     clearPendingFrames();
310 
311     return AMEDIA_OK;
312 }
313 
getFormat(AMediaFormat * meta)314 media_status_t MatroskaSource::getFormat(AMediaFormat *meta) {
315     return AMediaFormat_copy(meta, mExtractor->mTracks.itemAt(mTrackIndex).mMeta);
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 
BlockIterator(MatroskaExtractor * extractor,unsigned long trackNum,unsigned long index)320 BlockIterator::BlockIterator(
321         MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index)
322     : mExtractor(extractor),
323       mTrackNum(trackNum),
324       mIndex(index),
325       mCluster(NULL),
326       mBlockEntry(NULL),
327       mBlockEntryIndex(0) {
328     mTrackType = mExtractor->mSegment->GetTracks()->GetTrackByNumber(trackNum)->GetType();
329     reset();
330 }
331 
eos() const332 bool BlockIterator::eos() const {
333     return mCluster == NULL || mCluster->EOS();
334 }
335 
advance()336 void BlockIterator::advance() {
337     Mutex::Autolock autoLock(mExtractor->mLock);
338     advance_l();
339 }
340 
advance_l()341 void BlockIterator::advance_l() {
342     for (;;) {
343         long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
344         ALOGV("GetEntry returned %ld", res);
345 
346         long long pos;
347         long len;
348         if (res < 0) {
349             // Need to parse this cluster some more
350 
351             CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);
352 
353             res = mCluster->Parse(pos, len);
354             ALOGV("Parse returned %ld", res);
355 
356             if (res < 0) {
357                 // I/O error
358 
359                 ALOGE("Cluster::Parse returned result %ld", res);
360 
361                 mCluster = NULL;
362                 break;
363             }
364 
365             continue;
366         } else if (res == 0) {
367             // We're done with this cluster
368 
369             const mkvparser::Cluster *nextCluster;
370             res = mExtractor->mSegment->ParseNext(
371                     mCluster, nextCluster, pos, len);
372             ALOGV("ParseNext returned %ld", res);
373 
374             if (res != 0) {
375                 // EOF or error
376 
377                 mCluster = NULL;
378                 break;
379             }
380 
381             CHECK_EQ(res, 0);
382             CHECK(nextCluster != NULL);
383             CHECK(!nextCluster->EOS());
384 
385             mCluster = nextCluster;
386 
387             res = mCluster->Parse(pos, len);
388             ALOGV("Parse (2) returned %ld", res);
389 
390             if (res < 0) {
391                 // I/O error
392 
393                 ALOGE("Cluster::Parse returned result %ld", res);
394 
395                 mCluster = NULL;
396                 break;
397             }
398 
399             mBlockEntryIndex = 0;
400             continue;
401         }
402 
403         CHECK(mBlockEntry != NULL);
404         CHECK(mBlockEntry->GetBlock() != NULL);
405         ++mBlockEntryIndex;
406 
407         if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
408             break;
409         }
410     }
411 }
412 
reset()413 void BlockIterator::reset() {
414     Mutex::Autolock autoLock(mExtractor->mLock);
415 
416     mCluster = mExtractor->mSegment->GetFirst();
417     mBlockEntry = NULL;
418     mBlockEntryIndex = 0;
419 
420     do {
421         advance_l();
422     } while (!eos() && block()->GetTrackNumber() != mTrackNum);
423 }
424 
seek(int64_t seekTimeUs,bool isAudio,int64_t * actualFrameTimeUs)425 void BlockIterator::seek(
426         int64_t seekTimeUs, bool isAudio,
427         int64_t *actualFrameTimeUs) {
428     Mutex::Autolock autoLock(mExtractor->mLock);
429 
430     *actualFrameTimeUs = -1ll;
431 
432     if (seekTimeUs > INT64_MAX / 1000ll ||
433             seekTimeUs < INT64_MIN / 1000ll ||
434             (mExtractor->mSeekPreRollNs > 0 &&
435                     (seekTimeUs * 1000ll) < INT64_MIN + mExtractor->mSeekPreRollNs) ||
436             (mExtractor->mSeekPreRollNs < 0 &&
437                     (seekTimeUs * 1000ll) > INT64_MAX + mExtractor->mSeekPreRollNs)) {
438         ALOGE("cannot seek to %lld", (long long) seekTimeUs);
439         return;
440     }
441 
442     const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs;
443 
444     mkvparser::Segment* const pSegment = mExtractor->mSegment;
445 
446     // Special case the 0 seek to avoid loading Cues when the application
447     // extraneously seeks to 0 before playing.
448     if (seekTimeNs <= 0) {
449         ALOGV("Seek to beginning: %" PRId64, seekTimeUs);
450         mCluster = pSegment->GetFirst();
451         mBlockEntryIndex = 0;
452         do {
453             advance_l();
454         } while (!eos() && block()->GetTrackNumber() != mTrackNum);
455         return;
456     }
457 
458     ALOGV("Seeking to: %" PRId64, seekTimeUs);
459 
460     // If the Cues have not been located then find them.
461     const mkvparser::Cues* pCues = pSegment->GetCues();
462     const mkvparser::SeekHead* pSH = pSegment->GetSeekHead();
463     if (!pCues && pSH) {
464         const size_t count = pSH->GetCount();
465         const mkvparser::SeekHead::Entry* pEntry;
466         ALOGV("No Cues yet");
467 
468         for (size_t index = 0; index < count; index++) {
469             pEntry = pSH->GetEntry(index);
470 
471             if (pEntry->id == libwebm::kMkvCues) { // Cues ID
472                 long len; long long pos;
473                 pSegment->ParseCues(pEntry->pos, pos, len);
474                 pCues = pSegment->GetCues();
475                 ALOGV("Cues found");
476                 break;
477             }
478         }
479 
480         if (!pCues) {
481             ALOGV("No Cues in file,seek without cue data");
482             seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
483             return;
484         }
485     }
486     else if (!pSH) {
487         ALOGV("No SeekHead, seek without cue data");
488         seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
489         return;
490     }
491 
492     const mkvparser::CuePoint* pCP;
493     mkvparser::Tracks const *pTracks = pSegment->GetTracks();
494     while (!pCues->DoneParsing()) {
495         pCues->LoadCuePoint();
496         pCP = pCues->GetLast();
497         ALOGV("pCP = %s", pCP == NULL ? "NULL" : "not NULL");
498         if (pCP == NULL)
499             continue;
500 
501         size_t trackCount = mExtractor->mTracks.size();
502         for (size_t index = 0; index < trackCount; ++index) {
503             MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index);
504             const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum);
505             if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK
506                 track.mCuePoints.push_back(pCP);
507             }
508         }
509 
510         if (pCP->GetTime(pSegment) >= seekTimeNs) {
511             ALOGV("Parsed past relevant Cue");
512             break;
513         }
514     }
515 
516     const mkvparser::CuePoint::TrackPosition *pTP = NULL;
517     const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum);
518     if (thisTrack->GetType() == 1) { // video
519         MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex);
520         pTP = track.find(seekTimeNs);
521     } else {
522         // The Cue index is built around video keyframes
523         unsigned long int trackCount = pTracks->GetTracksCount();
524         for (size_t index = 0; index < trackCount; ++index) {
525             const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index);
526             if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) {
527                 ALOGV("Video track located at %zu", index);
528                 break;
529             }
530         }
531     }
532 
533 
534     // Always *search* based on the video track, but finalize based on mTrackNum
535     if (!pTP) {
536         ALOGE("Did not locate the video track for seeking");
537         seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
538         return;
539     }
540 
541     mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos);
542 
543     CHECK(mCluster);
544     CHECK(!mCluster->EOS());
545 
546     // mBlockEntryIndex starts at 0 but m_block starts at 1
547     CHECK_GT(pTP->m_block, 0);
548     mBlockEntryIndex = pTP->m_block - 1;
549 
550     for (;;) {
551         advance_l();
552 
553         if (eos()) break;
554 
555         if (isAudio || block()->IsKey()) {
556             // Accept the first key frame
557             int64_t frameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL;
558             if (thisTrack->GetType() == 1 || frameTimeUs >= seekTimeUs) {
559                 *actualFrameTimeUs = frameTimeUs;
560                 ALOGV("Requested seek point: %" PRId64 " actual: %" PRId64,
561                       seekTimeUs, *actualFrameTimeUs);
562                 break;
563             }
564         }
565     }
566 }
567 
block() const568 const mkvparser::Block *BlockIterator::block() const {
569     CHECK(!eos());
570 
571     return mBlockEntry->GetBlock();
572 }
573 
blockTimeUs() const574 int64_t BlockIterator::blockTimeUs() const {
575     if (mCluster == NULL || mBlockEntry == NULL) {
576         return -1;
577     }
578     return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
579 }
580 
seekwithoutcue_l(int64_t seekTimeUs,int64_t * actualFrameTimeUs)581 void BlockIterator::seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs) {
582     mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
583     const long status = mCluster->GetFirst(mBlockEntry);
584     if (status < 0) {  // error
585         ALOGE("get last blockenry failed!");
586         mCluster = NULL;
587         return;
588     }
589     mBlockEntryIndex = 0;
590     while (!eos() && ((block()->GetTrackNumber() != mTrackNum) || (blockTimeUs() < seekTimeUs))) {
591         advance_l();
592     }
593 
594     // video track will seek to the next key frame.
595     if (mTrackType == 1) {
596         while (!eos() && ((block()->GetTrackNumber() != mTrackNum) ||
597                       !mBlockEntry->GetBlock()->IsKey())) {
598             advance_l();
599         }
600     }
601     *actualFrameTimeUs = blockTimeUs();
602      ALOGV("seekTimeUs:%lld, actualFrameTimeUs:%lld, tracknum:%lld",
603               (long long)seekTimeUs, (long long)*actualFrameTimeUs, (long long)mTrackNum);
604 }
605 
606 ////////////////////////////////////////////////////////////////////////////////
607 
U24_AT(const uint8_t * ptr)608 static unsigned U24_AT(const uint8_t *ptr) {
609     return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
610 }
611 
uriDebugString(const char * uri)612 static AString uriDebugString(const char *uri) {
613     // find scheme
614     AString scheme;
615     for (size_t i = 0; i < strlen(uri); i++) {
616         const char c = uri[i];
617         if (!isascii(c)) {
618             break;
619         } else if (isalpha(c)) {
620             continue;
621         } else if (i == 0) {
622             // first character must be a letter
623             break;
624         } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
625             continue;
626         } else if (c != ':') {
627             break;
628         }
629         scheme = AString(uri, 0, i);
630         scheme.append("://<suppressed>");
631         return scheme;
632     }
633     return AString("<no-scheme URI suppressed>");
634 }
635 
clearPendingFrames()636 void MatroskaSource::clearPendingFrames() {
637     while (!mPendingFrames.empty()) {
638         MediaBufferHelper *frame = *mPendingFrames.begin();
639         mPendingFrames.erase(mPendingFrames.begin());
640 
641         frame->release();
642         frame = NULL;
643     }
644 }
645 
setWebmBlockCryptoInfo(MediaBufferHelper * mbuf)646 status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferHelper *mbuf) {
647     if (mbuf->range_length() < 1 || mbuf->range_length() - 1 > INT32_MAX) {
648         // 1-byte signal
649         return ERROR_MALFORMED;
650     }
651 
652     const uint8_t *data = (const uint8_t *)mbuf->data() + mbuf->range_offset();
653     bool encrypted = data[0] & 0x1;
654     bool partitioned = data[0] & 0x2;
655     if (encrypted && mbuf->range_length() < 9) {
656         // 1-byte signal + 8-byte IV
657         return ERROR_MALFORMED;
658     }
659 
660     AMediaFormat *meta = mbuf->meta_data();
661     if (encrypted) {
662         uint8_t ctrCounter[16] = { 0 };
663         const uint8_t *keyId;
664         size_t keyIdSize;
665         AMediaFormat *trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
666         AMediaFormat_getBuffer(trackMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY,
667                 (void**)&keyId, &keyIdSize);
668         AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_KEY, keyId, keyIdSize);
669         memcpy(ctrCounter, data + 1, 8);
670         AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_IV, ctrCounter, 16);
671         if (partitioned) {
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              * |               | num_partition |     Partition 0 offset ->     |
680              * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
681              * |     -> Partition 0 offset     |              ...              |
682              * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
683              * |             ...               |     Partition n-1 offset ->   |
684              * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
685              * |     -> Partition n-1 offset   |                               |
686              * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
687              * |                    Clear/encrypted sample data                |
688              * |                                                               |
689              * |                                                               |
690              * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
691              */
692             if (mbuf->range_length() < 10) {
693                 return ERROR_MALFORMED;
694             }
695             uint8_t numPartitions = data[9];
696             if (mbuf->range_length() - 10 < numPartitions * sizeof(uint32_t)) {
697                 return ERROR_MALFORMED;
698             }
699             std::vector<uint32_t> plainSizes, encryptedSizes;
700             uint32_t prev = 0;
701             uint32_t frameOffset = 10 + numPartitions * sizeof(uint32_t);
702             const uint32_t *partitions = reinterpret_cast<const uint32_t*>(data + 10);
703             for (uint32_t i = 0; i <= numPartitions; ++i) {
704                 uint32_t p_i = i < numPartitions
705                         ? ntohl(partitions[i])
706                         : (mbuf->range_length() - frameOffset);
707                 if (p_i < prev) {
708                     return ERROR_MALFORMED;
709                 }
710                 uint32_t size = p_i - prev;
711                 prev = p_i;
712                 if (i % 2) {
713                     encryptedSizes.push_back(size);
714                 } else {
715                     plainSizes.push_back(size);
716                 }
717             }
718             if (plainSizes.size() > encryptedSizes.size()) {
719                 encryptedSizes.push_back(0);
720             }
721             uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size();
722             uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size();
723             AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
724                     plainSizes.data(), sizeofPlainSizes);
725             AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
726                     encryptedSizes.data(), sizeofEncryptedSizes);
727             mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset);
728         } else {
729             /*
730              *  0                   1                   2                   3
731              *  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
732              *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
733              *  |  Signal Byte  |                                               |
734              *  +-+-+-+-+-+-+-+-+             IV                                |
735              *  |                                                               |
736              *  |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
737              *  |               |                                               |
738              *  |-+-+-+-+-+-+-+-+                                               |
739              *  :               Bytes 1..N of encrypted frame                   :
740              *  |                                                               |
741              *  |                                                               |
742              *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
743              */
744             int32_t plainSizes[] = { 0 };
745             int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
746             AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
747                     plainSizes, sizeof(plainSizes));
748             AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
749                     encryptedSizes, sizeof(encryptedSizes));
750             mbuf->set_range(9, mbuf->range_length() - 9);
751         }
752     } else {
753         /*
754          *  0                   1                   2                   3
755          *  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
756          *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
757          *  |  Signal Byte  |                                               |
758          *  +-+-+-+-+-+-+-+-+                                               |
759          *  :               Bytes 1..N of unencrypted frame                 :
760          *  |                                                               |
761          *  |                                                               |
762          *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
763          */
764         int32_t plainSizes[] = { static_cast<int32_t>(mbuf->range_length() - 1) };
765         int32_t encryptedSizes[] = { 0 };
766         AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
767                 plainSizes, sizeof(plainSizes));
768         AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
769                 encryptedSizes, sizeof(encryptedSizes));
770         mbuf->set_range(1, mbuf->range_length() - 1);
771     }
772 
773     return OK;
774 }
775 
readBlock()776 media_status_t MatroskaSource::readBlock() {
777     CHECK(mPendingFrames.empty());
778 
779     if (mBlockIter.eos()) {
780         return AMEDIA_ERROR_END_OF_STREAM;
781     }
782 
783     const mkvparser::Block *block = mBlockIter.block();
784 
785     int64_t timeUs = mBlockIter.blockTimeUs();
786 
787     for (int i = 0; i < block->GetFrameCount(); ++i) {
788         MatroskaExtractor::TrackInfo *trackInfo = &mExtractor->mTracks.editItemAt(mTrackIndex);
789         const mkvparser::Block::Frame &frame = block->GetFrame(i);
790         size_t len = frame.len;
791         if (SIZE_MAX - len < trackInfo->mHeaderLen) {
792             return AMEDIA_ERROR_MALFORMED;
793         }
794 
795         len += trackInfo->mHeaderLen;
796         MediaBufferHelper *mbuf;
797         mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */, len /* requested size */);
798         mbuf->set_range(0, len);
799         uint8_t *data = static_cast<uint8_t *>(mbuf->data());
800         if (trackInfo->mHeader) {
801             memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen);
802         }
803 
804         AMediaFormat *meta = mbuf->meta_data();
805         AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
806         AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, block->IsKey());
807 
808         if (mType == VORBIS) {
809             int32_t sampleRate;
810             if (!AMediaFormat_getInt32(trackInfo->mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE,
811                                        &sampleRate)) {
812                 return AMEDIA_ERROR_MALFORMED;
813             }
814             int64_t durationUs;
815             if (!AMediaFormat_getInt64(trackInfo->mMeta, AMEDIAFORMAT_KEY_DURATION,
816                                        &durationUs)) {
817                 return AMEDIA_ERROR_MALFORMED;
818             }
819             // TODO: Explore if this can be handled similar to MPEG4 extractor where padding is
820             // signalled instead of VALID_SAMPLES
821             // Remaining valid samples in Vorbis track
822             if (durationUs > timeUs) {
823                 int32_t validSamples = ((durationUs - timeUs) * sampleRate) / 1000000ll;
824                 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, validSamples);
825             }
826         }
827 
828         status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
829         if (err == OK
830                 && mExtractor->mIsWebm
831                 && trackInfo->mEncrypted) {
832             err = setWebmBlockCryptoInfo(mbuf);
833         }
834 
835         if (err != OK) {
836             mPendingFrames.clear();
837 
838             mBlockIter.advance();
839             mbuf->release();
840             return AMEDIA_ERROR_UNKNOWN;
841         }
842 
843         mPendingFrames.push_back(mbuf);
844     }
845 
846     mBlockIter.advance();
847 
848     return AMEDIA_OK;
849 }
850 
851 //the value of kMP3HeaderMask is from MP3Extractor
852 static const uint32_t kMP3HeaderMask = 0xfffe0c00;
853 
findMP3Header(uint32_t * header,const uint8_t * dataSource,int length,int * outStartPos)854 media_status_t MatroskaSource::findMP3Header(uint32_t * header,
855         const uint8_t *dataSource, int length, int *outStartPos) {
856     if (NULL == header) {
857         ALOGE("header is null!");
858         return AMEDIA_ERROR_END_OF_STREAM;
859     }
860 
861     //to find header start position
862     if (0 != *header) {
863         if (NULL == dataSource) {
864             *outStartPos = -1;
865             return AMEDIA_OK;
866         }
867         uint32_t tmpCode = 0;
868         for (int i = 0; i < length; i++) {
869             tmpCode = (tmpCode << 8) + dataSource[i];
870             if ((tmpCode & kMP3HeaderMask) == (*header & kMP3HeaderMask)) {
871                 *outStartPos = i - 3;
872                 return AMEDIA_OK;
873             }
874         }
875         *outStartPos = -1;
876         return AMEDIA_OK;
877     }
878 
879     //to find mp3 header
880     uint32_t code = 0;
881     while (0 == *header) {
882         while (mPendingFrames.empty()) {
883             media_status_t err = readBlock();
884             if (err != OK) {
885                 clearPendingFrames();
886                 return err;
887             }
888         }
889         MediaBufferHelper *frame = *mPendingFrames.begin();
890         size_t size = frame->range_length();
891         size_t offset = frame->range_offset();
892         size_t i;
893         size_t frame_size;
894         for (i = 0; i < size; i++) {
895             ALOGV("data[%zu]=%x", i, *((uint8_t*)frame->data() + offset + i));
896             code = (code << 8) + *((uint8_t*)frame->data() + offset + i);
897             if (GetMPEGAudioFrameSize(code, &frame_size, NULL, NULL, NULL)) {
898                 *header = code;
899                 mBlockIter.reset();
900                 clearPendingFrames();
901                 return AMEDIA_OK;
902             }
903         }
904     }
905 
906     return AMEDIA_ERROR_END_OF_STREAM;
907 }
908 
mp3FrameRead(MediaBufferHelper ** out,const ReadOptions * options,int64_t targetSampleTimeUs)909 media_status_t MatroskaSource::mp3FrameRead(
910         MediaBufferHelper **out, const ReadOptions *options,
911         int64_t targetSampleTimeUs) {
912     MediaBufferHelper *frame = *mPendingFrames.begin();
913     int64_t seekTimeUs;
914     ReadOptions::SeekMode mode;
915     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
916         CHECK(AMediaFormat_getInt64(frame->meta_data(),
917                     AMEDIAFORMAT_KEY_TIME_US, &mCurrentTS));
918         if (mCurrentTS < 0) {
919             mCurrentTS = 0;
920             AMediaFormat_setInt64(frame->meta_data(),
921                     AMEDIAFORMAT_KEY_TIME_US, mCurrentTS);
922         }
923     }
924 
925     int32_t start = -1;
926     while (start < 0) {
927         //find header start position
928         findMP3Header(&mMP3Header,
929             (const uint8_t*)frame->data() + frame->range_offset(),
930             frame->range_length(), &start);
931         ALOGV("start=%d, frame->range_length() = %zu, frame->range_offset() =%zu",
932                       start, frame->range_length(), frame->range_offset());
933         if (start >= 0)
934             break;
935         frame->release();
936         mPendingFrames.erase(mPendingFrames.begin());
937         while (mPendingFrames.empty()) {
938             media_status_t err = readBlock();
939             if (err != OK) {
940                 clearPendingFrames();
941                 return err;
942             }
943         }
944         frame = *mPendingFrames.begin();
945     }
946 
947     frame->set_range(frame->range_offset() + start, frame->range_length() - start);
948 
949     uint32_t header = *(uint32_t*)((uint8_t*)frame->data() + frame->range_offset());
950     header = ((header >> 24) & 0xff) | ((header >> 8) & 0xff00) |
951                     ((header << 8) & 0xff0000) | ((header << 24) & 0xff000000);
952     size_t frame_size;
953     int out_sampling_rate;
954     int out_channels;
955     int out_bitrate;
956     if (!GetMPEGAudioFrameSize(header, &frame_size,
957                                &out_sampling_rate, &out_channels, &out_bitrate)) {
958         ALOGE("MP3 Header read fail!!");
959         return AMEDIA_ERROR_UNSUPPORTED;
960     }
961 
962     MediaBufferHelper *buffer;
963     mBufferGroup->acquire_buffer(&buffer, false /* nonblocking */, frame_size /* requested size */);
964     buffer->set_range(0, frame_size);
965 
966     uint8_t *data = static_cast<uint8_t *>(buffer->data());
967     ALOGV("MP3 frame %zu frame->range_length() %zu", frame_size, frame->range_length());
968 
969     if (frame_size > frame->range_length()) {
970         memcpy(data, (uint8_t*)(frame->data()) + frame->range_offset(), frame->range_length());
971         size_t sumSize = 0;
972         sumSize += frame->range_length();
973         size_t needSize = frame_size - frame->range_length();
974         frame->release();
975         mPendingFrames.erase(mPendingFrames.begin());
976         while (mPendingFrames.empty()) {
977             media_status_t err = readBlock();
978             if (err != OK) {
979                 clearPendingFrames();
980                 return err;
981             }
982         }
983         frame = *mPendingFrames.begin();
984         size_t offset = frame->range_offset();
985         size_t size = frame->range_length();
986 
987         // the next buffer frame is not enough to fullfill mp3 frame,
988         // we have to read until mp3 frame is completed.
989         while (size < needSize) {
990             memcpy(data + sumSize, (uint8_t*)(frame->data()) + offset, size);
991             needSize -= size;
992             sumSize += size;
993             frame->release();
994             mPendingFrames.erase(mPendingFrames.begin());
995             while (mPendingFrames.empty()) {
996                 media_status_t err = readBlock();
997                 if (err != OK) {
998                     clearPendingFrames();
999                     return err;
1000                 }
1001             }
1002             frame = *mPendingFrames.begin();
1003             offset = frame->range_offset();
1004             size = frame->range_length();
1005         }
1006         memcpy(data + sumSize, (uint8_t*)(frame->data()) + offset, needSize);
1007         frame->set_range(offset + needSize, size - needSize);
1008      } else {
1009         size_t offset = frame->range_offset();
1010         size_t size = frame->range_length();
1011         memcpy(data, (uint8_t*)(frame->data()) + offset, frame_size);
1012         frame->set_range(offset + frame_size, size - frame_size);
1013     }
1014     if (frame->range_length() < 4) {
1015         frame->release();
1016         frame = NULL;
1017         mPendingFrames.erase(mPendingFrames.begin());
1018     }
1019     ALOGV("MatroskaSource::read MP3 frame kKeyTime=%lld,kKeyTargetTime=%lld",
1020                     (long long)mCurrentTS, (long long)targetSampleTimeUs);
1021     AMediaFormat_setInt64(buffer->meta_data(),
1022             AMEDIAFORMAT_KEY_TIME_US, mCurrentTS);
1023     mCurrentTS += (int64_t)frame_size * 8000ll / out_bitrate;
1024 
1025     if (targetSampleTimeUs >= 0ll)
1026         AMediaFormat_setInt64(buffer->meta_data(),
1027                 AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
1028     *out = buffer;
1029     ALOGV("MatroskaSource::read MP3, keyTime=%lld for next frame", (long long)mCurrentTS);
1030     return AMEDIA_OK;
1031 }
1032 
read(MediaBufferHelper ** out,const ReadOptions * options)1033 media_status_t MatroskaSource::read(
1034         MediaBufferHelper **out, const ReadOptions *options) {
1035     *out = NULL;
1036 
1037     int64_t targetSampleTimeUs = -1ll;
1038 
1039     int64_t seekTimeUs;
1040     ReadOptions::SeekMode mode;
1041     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
1042         if (mode == ReadOptions::SEEK_FRAME_INDEX) {
1043             return AMEDIA_ERROR_UNSUPPORTED;
1044         }
1045 
1046         if (!mExtractor->isLiveStreaming()) {
1047             clearPendingFrames();
1048 
1049             // The audio we want is located by using the Cues to seek the video
1050             // stream to find the target Cluster then iterating to finalize for
1051             // audio.
1052             int64_t actualFrameTimeUs;
1053             mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs);
1054             if (mode == ReadOptions::SEEK_CLOSEST) {
1055                 targetSampleTimeUs = actualFrameTimeUs;
1056             }
1057         }
1058     }
1059 
1060     while (mPendingFrames.empty()) {
1061         media_status_t err = readBlock();
1062 
1063         if (err != OK) {
1064             clearPendingFrames();
1065 
1066             return err;
1067         }
1068     }
1069 
1070     if (mType == MP3) {
1071         return mp3FrameRead(out, options, targetSampleTimeUs);
1072     }
1073 
1074     MediaBufferHelper *frame = *mPendingFrames.begin();
1075     mPendingFrames.erase(mPendingFrames.begin());
1076 
1077     if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) {
1078         if (targetSampleTimeUs >= 0ll) {
1079             AMediaFormat_setInt64(frame->meta_data(),
1080                     AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
1081         }
1082 
1083         if (mType == PCM) {
1084             int32_t bitPerFrame = 16;
1085             int32_t bigEndian = 0;
1086             AMediaFormat *meta = AMediaFormat_new();
1087             if (getFormat(meta) == AMEDIA_OK && meta != NULL) {
1088                 AMediaFormat_getInt32(meta,
1089                                 AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitPerFrame);
1090                 AMediaFormat_getInt32(meta,
1091                                 AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, &bigEndian);
1092             }
1093             AMediaFormat_delete(meta);
1094             if (bigEndian == 1 && bitPerFrame == 16) {
1095                 // Big-endian -> little-endian
1096                 uint16_t *dstData = (uint16_t *)frame->data() + frame->range_offset();
1097                 uint16_t *srcData = (uint16_t *)frame->data() + frame->range_offset();
1098                 for (size_t i = 0; i < frame->range_length() / 2; i++) {
1099                     dstData[i] = ntohs(srcData[i]);
1100                 }
1101             }
1102         }
1103 
1104         *out = frame;
1105 
1106         return AMEDIA_OK;
1107     }
1108 
1109     // Each input frame contains one or more NAL fragments, each fragment
1110     // is prefixed by mNALSizeLen bytes giving the fragment length,
1111     // followed by a corresponding number of bytes containing the fragment.
1112     // We output all these fragments into a single large buffer separated
1113     // by startcodes (0x00 0x00 0x00 0x01).
1114     //
1115     // When mNALSizeLen is 0, we assume the data is already in the format
1116     // desired.
1117 
1118     const uint8_t *srcPtr =
1119         (const uint8_t *)frame->data() + frame->range_offset();
1120 
1121     size_t srcSize = frame->range_length();
1122 
1123     size_t dstSize = 0;
1124     MediaBufferHelper *buffer = NULL;
1125     uint8_t *dstPtr = NULL;
1126 
1127     for (int32_t pass = 0; pass < 2; ++pass) {
1128         size_t srcOffset = 0;
1129         size_t dstOffset = 0;
1130         while (srcOffset + mNALSizeLen <= srcSize) {
1131             size_t NALsize;
1132             switch (mNALSizeLen) {
1133                 case 1: NALsize = srcPtr[srcOffset]; break;
1134                 case 2: NALsize = U16_AT(srcPtr + srcOffset); break;
1135                 case 3: NALsize = U24_AT(srcPtr + srcOffset); break;
1136                 case 4: NALsize = U32_AT(srcPtr + srcOffset); break;
1137                 default:
1138                     TRESPASS();
1139             }
1140 
1141             if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) {
1142                 frame->release();
1143                 frame = NULL;
1144 
1145                 return AMEDIA_ERROR_MALFORMED;
1146             } else if (srcOffset + mNALSizeLen + NALsize > srcSize) {
1147                 break;
1148             }
1149 
1150             if (pass == 1) {
1151                 memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4);
1152 
1153                 if (frame != buffer) {
1154                     memcpy(&dstPtr[dstOffset + 4],
1155                            &srcPtr[srcOffset + mNALSizeLen],
1156                            NALsize);
1157                 }
1158             }
1159 
1160             dstOffset += 4;  // 0x00 00 00 01
1161             dstOffset += NALsize;
1162 
1163             srcOffset += mNALSizeLen + NALsize;
1164         }
1165 
1166         if (srcOffset < srcSize) {
1167             // There were trailing bytes or not enough data to complete
1168             // a fragment.
1169 
1170             frame->release();
1171             frame = NULL;
1172 
1173             return AMEDIA_ERROR_MALFORMED;
1174         }
1175 
1176         if (pass == 0) {
1177             dstSize = dstOffset;
1178 
1179             if (dstSize == srcSize && mNALSizeLen == 4) {
1180                 // In this special case we can re-use the input buffer by substituting
1181                 // each 4-byte nal size with a 4-byte start code
1182                 buffer = frame;
1183             } else {
1184                 mBufferGroup->acquire_buffer(
1185                         &buffer, false /* nonblocking */, dstSize /* requested size */);
1186                 buffer->set_range(0, dstSize);
1187             }
1188 
1189             AMediaFormat *frameMeta = frame->meta_data();
1190             int64_t timeUs;
1191             CHECK(AMediaFormat_getInt64(frameMeta, AMEDIAFORMAT_KEY_TIME_US, &timeUs));
1192             int32_t isSync;
1193             CHECK(AMediaFormat_getInt32(frameMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, &isSync));
1194 
1195             AMediaFormat *bufMeta = buffer->meta_data();
1196             AMediaFormat_setInt64(bufMeta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
1197             AMediaFormat_setInt32(bufMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, isSync);
1198 
1199             dstPtr = (uint8_t *)buffer->data();
1200         }
1201     }
1202 
1203     if (frame != buffer) {
1204         frame->release();
1205         frame = NULL;
1206     }
1207 
1208     if (targetSampleTimeUs >= 0ll) {
1209         AMediaFormat_setInt64(buffer->meta_data(),
1210                 AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
1211     }
1212 
1213     *out = buffer;
1214 
1215     return AMEDIA_OK;
1216 }
1217 
1218 ////////////////////////////////////////////////////////////////////////////////
1219 
1220 enum WaveID {
1221     MKV_RIFF_WAVE_FORMAT_PCM = 0x0001,
1222     MKV_RIFF_WAVE_FORMAT_ADPCM_ms = 0x0002,
1223     MKV_RIFF_WAVE_FORMAT_ADPCM_ima_wav = 0x0011,
1224     MKV_RIFF_WAVE_FORMAT_MPEGL12 = 0x0050,
1225     MKV_RIFF_WAVE_FORMAT_MPEGL3 = 0x0055,
1226     MKV_RIFF_WAVE_FORMAT_WMAV1 = 0x0160,
1227     MKV_RIFF_WAVE_FORMAT_WMAV2 = 0x0161,
1228 };
1229 
MKVWave2MIME(uint16_t id)1230 static const char *MKVWave2MIME(uint16_t id) {
1231     switch (id) {
1232         case  MKV_RIFF_WAVE_FORMAT_MPEGL12:
1233             return MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II;
1234 
1235         case  MKV_RIFF_WAVE_FORMAT_MPEGL3:
1236             return MEDIA_MIMETYPE_AUDIO_MPEG;
1237 
1238         case MKV_RIFF_WAVE_FORMAT_PCM:
1239             return MEDIA_MIMETYPE_AUDIO_RAW;
1240 
1241         case MKV_RIFF_WAVE_FORMAT_ADPCM_ms:
1242             return MEDIA_MIMETYPE_AUDIO_MS_ADPCM;
1243         case MKV_RIFF_WAVE_FORMAT_ADPCM_ima_wav:
1244             return MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM;
1245 
1246         case MKV_RIFF_WAVE_FORMAT_WMAV1:
1247         case MKV_RIFF_WAVE_FORMAT_WMAV2:
1248             return MEDIA_MIMETYPE_AUDIO_WMA;
1249         default:
1250             ALOGW("unknown wave %x", id);
1251             return "";
1252     };
1253 }
1254 
isMkvAudioCsdSizeOK(const char * mime,size_t csdSize)1255 static bool isMkvAudioCsdSizeOK(const char* mime, size_t csdSize) {
1256     if ((!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MS_ADPCM) && csdSize < 50) ||
1257         (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) && csdSize < 20) ||
1258         (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_WMA) && csdSize < 28) ||
1259         (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) && csdSize < 30)) {
1260         return false;
1261     }
1262     return true;
1263 }
1264 
1265 // trans all FOURCC  to lower char
FourCCtoLower(uint32_t fourcc)1266 static uint32_t FourCCtoLower(uint32_t fourcc) {
1267     uint8_t ch_1 = tolower((fourcc >> 24) & 0xff);
1268     uint8_t ch_2 = tolower((fourcc >> 16) & 0xff);
1269     uint8_t ch_3 = tolower((fourcc >> 8) & 0xff);
1270     uint8_t ch_4 = tolower((fourcc) & 0xff);
1271     uint32_t fourcc_out = ch_1 << 24 | ch_2 << 16 | ch_3 << 8 | ch_4;
1272 
1273     return fourcc_out;
1274 }
1275 
MKVFourCC2MIME(uint32_t fourcc)1276 static const char *MKVFourCC2MIME(uint32_t fourcc) {
1277     ALOGV("MKVFourCC2MIME fourcc 0x%8.8x", fourcc);
1278     uint32_t lowerFourcc = FourCCtoLower(fourcc);
1279     switch (lowerFourcc) {
1280         case FOURCC("mp4v"):
1281             return MEDIA_MIMETYPE_VIDEO_MPEG4;
1282 
1283         case FOURCC("s263"):
1284         case FOURCC("h263"):
1285             return MEDIA_MIMETYPE_VIDEO_H263;
1286 
1287         case FOURCC("avc1"):
1288         case FOURCC("h264"):
1289             return MEDIA_MIMETYPE_VIDEO_AVC;
1290 
1291         case FOURCC("mpg2"):
1292             return MEDIA_MIMETYPE_VIDEO_MPEG2;
1293 
1294         case FOURCC("xvid"):
1295             return MEDIA_MIMETYPE_VIDEO_XVID;
1296 
1297         case FOURCC("divx"):
1298         case FOURCC("dx50"):
1299             return MEDIA_MIMETYPE_VIDEO_DIVX;
1300 
1301         case FOURCC("div3"):
1302         case FOURCC("div4"):
1303             return MEDIA_MIMETYPE_VIDEO_DIVX3;
1304 
1305         case FOURCC("mjpg"):
1306         case FOURCC("mppg"):
1307             return MEDIA_MIMETYPE_VIDEO_MJPEG;
1308 
1309         default:
1310             char fourccString[5];
1311             MakeFourCCString(fourcc, fourccString);
1312             ALOGW("mkv unsupport fourcc %s", fourccString);
1313             return "";
1314     }
1315 }
1316 
1317 
MatroskaExtractor(DataSourceHelper * source)1318 MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source)
1319     : mDataSource(source),
1320       mReader(new DataSourceBaseReader(mDataSource)),
1321       mSegment(NULL),
1322       mExtractedThumbnails(false),
1323       mIsWebm(false),
1324       mSeekPreRollNs(0) {
1325     off64_t size;
1326     mIsLiveStreaming =
1327         (mDataSource->flags()
1328             & (DataSourceBase::kWantsPrefetching
1329                 | DataSourceBase::kIsCachingDataSource))
1330         && mDataSource->getSize(&size) != OK;
1331 
1332     mkvparser::EBMLHeader ebmlHeader;
1333     long long pos;
1334     if (ebmlHeader.Parse(mReader, pos) < 0) {
1335         return;
1336     }
1337 
1338     if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) {
1339         mIsWebm = true;
1340     }
1341 
1342     long long ret =
1343         mkvparser::Segment::CreateInstance(mReader, pos, mSegment);
1344 
1345     if (ret) {
1346         CHECK(mSegment == NULL);
1347         return;
1348     }
1349 
1350     if (mIsLiveStreaming) {
1351         // from mkvparser::Segment::Load(), but stop at first cluster
1352         ret = mSegment->ParseHeaders();
1353         if (ret == 0) {
1354             long len;
1355             ret = mSegment->LoadCluster(pos, len);
1356             if (ret >= 1) {
1357                 // no more clusters
1358                 ret = 0;
1359             }
1360         } else if (ret > 0) {
1361             ret = mkvparser::E_BUFFER_NOT_FULL;
1362         }
1363     } else {
1364         ret = mSegment->ParseHeaders();
1365         if (ret < 0) {
1366             ALOGE("Segment parse header return fail %lld", ret);
1367             delete mSegment;
1368             mSegment = NULL;
1369             return;
1370         } else if (ret == 0) {
1371             const mkvparser::Cues* mCues = mSegment->GetCues();
1372             const mkvparser::SeekHead* mSH = mSegment->GetSeekHead();
1373             if ((mCues == NULL) && (mSH != NULL)) {
1374                 size_t count = mSH->GetCount();
1375                 const mkvparser::SeekHead::Entry* mEntry;
1376                 for (size_t index = 0; index < count; index++) {
1377                     mEntry = mSH->GetEntry(index);
1378                     if (mEntry->id == libwebm::kMkvCues) { // Cues ID
1379                         long len;
1380                         long long pos;
1381                         mSegment->ParseCues(mEntry->pos, pos, len);
1382                         mCues = mSegment->GetCues();
1383                         ALOGV("find cue data by seekhead");
1384                         break;
1385                     }
1386                 }
1387             }
1388 
1389             if (mCues) {
1390                 long len;
1391                 ret = mSegment->LoadCluster(pos, len);
1392                 ALOGV("has Cue data, Cluster num=%ld", mSegment->GetCount());
1393             } else  {
1394                 long status_Load = mSegment->Load();
1395                 ALOGW("no Cue data,Segment Load status:%ld",status_Load);
1396             }
1397         } else if (ret > 0) {
1398             ret = mkvparser::E_BUFFER_NOT_FULL;
1399         }
1400     }
1401 
1402     if (ret < 0) {
1403         char uri[1024];
1404         if(!mDataSource->getUri(uri, sizeof(uri))) {
1405             uri[0] = '\0';
1406         }
1407         ALOGW("Corrupt %s source: %s", mIsWebm ? "webm" : "matroska",
1408                 uriDebugString(uri).c_str());
1409         delete mSegment;
1410         mSegment = NULL;
1411         return;
1412     }
1413 
1414 #if 0
1415     const mkvparser::SegmentInfo *info = mSegment->GetInfo();
1416     ALOGI("muxing app: %s, writing app: %s",
1417          info->GetMuxingAppAsUTF8(),
1418          info->GetWritingAppAsUTF8());
1419 #endif
1420 
1421     addTracks();
1422 }
1423 
~MatroskaExtractor()1424 MatroskaExtractor::~MatroskaExtractor() {
1425     delete mSegment;
1426     mSegment = NULL;
1427 
1428     delete mReader;
1429     mReader = NULL;
1430 
1431     delete mDataSource;
1432 
1433     for (size_t i = 0; i < mTracks.size(); ++i) {
1434         TrackInfo *info = &mTracks.editItemAt(i);
1435         if (info->mMeta) {
1436             AMediaFormat_delete(info->mMeta);
1437         }
1438     }
1439 }
1440 
countTracks()1441 size_t MatroskaExtractor::countTracks() {
1442     return mTracks.size();
1443 }
1444 
getTrack(size_t index)1445 MediaTrackHelper *MatroskaExtractor::getTrack(size_t index) {
1446     if (index >= mTracks.size()) {
1447         return NULL;
1448     }
1449 
1450     return new MatroskaSource(this, index);
1451 }
1452 
getTrackMetaData(AMediaFormat * meta,size_t index,uint32_t flags)1453 media_status_t MatroskaExtractor::getTrackMetaData(
1454         AMediaFormat *meta,
1455         size_t index, uint32_t flags) {
1456     if (index >= mTracks.size()) {
1457         return AMEDIA_ERROR_UNKNOWN;
1458     }
1459 
1460     if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
1461             && !isLiveStreaming()) {
1462         findThumbnails();
1463         mExtractedThumbnails = true;
1464     }
1465 
1466     return AMediaFormat_copy(meta, mTracks.itemAt(index).mMeta);
1467 }
1468 
isLiveStreaming() const1469 bool MatroskaExtractor::isLiveStreaming() const {
1470     return mIsLiveStreaming;
1471 }
1472 
bytesForSize(size_t size)1473 static int bytesForSize(size_t size) {
1474     // use at most 28 bits (4 times 7)
1475     CHECK(size <= 0xfffffff);
1476 
1477     if (size > 0x1fffff) {
1478         return 4;
1479     } else if (size > 0x3fff) {
1480         return 3;
1481     } else if (size > 0x7f) {
1482         return 2;
1483     }
1484     return 1;
1485 }
1486 
storeSize(uint8_t * data,size_t & idx,size_t size)1487 static void storeSize(uint8_t *data, size_t &idx, size_t size) {
1488     int numBytes = bytesForSize(size);
1489     idx += numBytes;
1490 
1491     data += idx;
1492     size_t next = 0;
1493     while (numBytes--) {
1494         *--data = (size & 0x7f) | next;
1495         size >>= 7;
1496         next = 0x80;
1497     }
1498 }
1499 
addESDSFromCodecPrivate(AMediaFormat * meta,bool isAudio,const void * priv,size_t privSize)1500 static void addESDSFromCodecPrivate(
1501         AMediaFormat *meta,
1502         bool isAudio, const void *priv, size_t privSize) {
1503 
1504     int privSizeBytesRequired = bytesForSize(privSize);
1505     int esdsSize2 = 14 + privSizeBytesRequired + privSize;
1506     int esdsSize2BytesRequired = bytesForSize(esdsSize2);
1507     int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2;
1508     int esdsSize1BytesRequired = bytesForSize(esdsSize1);
1509     size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1;
1510     uint8_t *esds = new uint8_t[esdsSize];
1511 
1512     size_t idx = 0;
1513     esds[idx++] = 0x03;
1514     storeSize(esds, idx, esdsSize1);
1515     esds[idx++] = 0x00; // ES_ID
1516     esds[idx++] = 0x00; // ES_ID
1517     esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
1518     esds[idx++] = 0x04;
1519     storeSize(esds, idx, esdsSize2);
1520     esds[idx++] = isAudio ? 0x40   // Audio ISO/IEC 14496-3
1521                           : 0x20;  // Visual ISO/IEC 14496-2
1522     for (int i = 0; i < 12; i++) {
1523         esds[idx++] = 0x00;
1524     }
1525     esds[idx++] = 0x05;
1526     storeSize(esds, idx, privSize);
1527     memcpy(esds + idx, priv, privSize);
1528 
1529     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, priv, privSize);
1530 
1531     delete[] esds;
1532     esds = NULL;
1533 }
1534 
addVorbisCodecInfo(AMediaFormat * meta,const void * _codecPrivate,size_t codecPrivateSize)1535 status_t addVorbisCodecInfo(
1536         AMediaFormat *meta,
1537         const void *_codecPrivate, size_t codecPrivateSize) {
1538     // hexdump(_codecPrivate, codecPrivateSize);
1539 
1540     if (codecPrivateSize < 1) {
1541         return ERROR_MALFORMED;
1542     }
1543 
1544     const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
1545 
1546     if (codecPrivate[0] != 0x02) {
1547         return ERROR_MALFORMED;
1548     }
1549 
1550     // codecInfo starts with two lengths, len1 and len2, that are
1551     // "Xiph-style-lacing encoded"...
1552 
1553     size_t offset = 1;
1554     size_t len1 = 0;
1555     while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
1556         if (len1 > (SIZE_MAX - 0xff)) {
1557             return ERROR_MALFORMED; // would overflow
1558         }
1559         len1 += 0xff;
1560         ++offset;
1561     }
1562     if (offset >= codecPrivateSize) {
1563         return ERROR_MALFORMED;
1564     }
1565     if (len1 > (SIZE_MAX - codecPrivate[offset])) {
1566         return ERROR_MALFORMED; // would overflow
1567     }
1568     len1 += codecPrivate[offset++];
1569 
1570     size_t len2 = 0;
1571     while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
1572         if (len2 > (SIZE_MAX - 0xff)) {
1573             return ERROR_MALFORMED; // would overflow
1574         }
1575         len2 += 0xff;
1576         ++offset;
1577     }
1578     if (offset >= codecPrivateSize) {
1579         return ERROR_MALFORMED;
1580     }
1581     if (len2 > (SIZE_MAX - codecPrivate[offset])) {
1582         return ERROR_MALFORMED; // would overflow
1583     }
1584     len2 += codecPrivate[offset++];
1585 
1586     if (len1 > SIZE_MAX - len2 || offset > SIZE_MAX - (len1 + len2) ||
1587             codecPrivateSize < offset + len1 + len2) {
1588         return ERROR_MALFORMED;
1589     }
1590 
1591     if (codecPrivate[offset] != 0x01) {
1592         return ERROR_MALFORMED;
1593     }
1594     // formerly kKeyVorbisInfo
1595     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, &codecPrivate[offset], len1);
1596 
1597     offset += len1;
1598     if (codecPrivate[offset] != 0x03) {
1599         return ERROR_MALFORMED;
1600     }
1601 
1602     offset += len2;
1603     if (codecPrivate[offset] != 0x05) {
1604         return ERROR_MALFORMED;
1605     }
1606 
1607     // formerly kKeyVorbisBooks
1608     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_1,
1609             &codecPrivate[offset], codecPrivateSize - offset);
1610 
1611     return OK;
1612 }
1613 
addFlacMetadata(AMediaFormat * meta,const void * codecPrivate,size_t codecPrivateSize)1614 static status_t addFlacMetadata(
1615         AMediaFormat *meta,
1616         const void *codecPrivate, size_t codecPrivateSize) {
1617     // hexdump(codecPrivate, codecPrivateSize);
1618 
1619     // formerly kKeyFlacMetadata
1620     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
1621 
1622     int32_t maxInputSize = 64 << 10;
1623     FLACDecoder *flacDecoder = FLACDecoder::Create();
1624     if (flacDecoder != NULL
1625             && flacDecoder->parseMetadata((const uint8_t*)codecPrivate, codecPrivateSize) == OK) {
1626         FLAC__StreamMetadata_StreamInfo streamInfo = flacDecoder->getStreamInfo();
1627         maxInputSize = streamInfo.max_framesize;
1628         if (maxInputSize == 0) {
1629             // In case max framesize is not available, use raw data size as max framesize,
1630             // assuming there is no expansion.
1631             if (streamInfo.max_blocksize != 0
1632                     && streamInfo.channels != 0
1633                     && ((streamInfo.bits_per_sample + 7) / 8) >
1634                         INT32_MAX / streamInfo.max_blocksize / streamInfo.channels) {
1635                 delete flacDecoder;
1636                 return ERROR_MALFORMED;
1637             }
1638             maxInputSize = ((streamInfo.bits_per_sample + 7) / 8)
1639                 * streamInfo.max_blocksize * streamInfo.channels;
1640         }
1641     }
1642     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, maxInputSize);
1643 
1644     delete flacDecoder;
1645     return OK;
1646 }
1647 
synthesizeAVCC(TrackInfo * trackInfo,size_t index)1648 status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) {
1649     BlockIterator iter(this, trackInfo->mTrackNum, index);
1650     if (iter.eos()) {
1651         return ERROR_MALFORMED;
1652     }
1653 
1654     const mkvparser::Block *block = iter.block();
1655     if (block->GetFrameCount() <= 0) {
1656         return ERROR_MALFORMED;
1657     }
1658 
1659     const mkvparser::Block::Frame &frame = block->GetFrame(0);
1660     auto tmpData = heapbuffer<unsigned char>(frame.len);
1661     long n = frame.Read(mReader, tmpData.get());
1662     if (n != 0) {
1663         return ERROR_MALFORMED;
1664     }
1665 
1666     if (!MakeAVCCodecSpecificData(trackInfo->mMeta, tmpData.get(), frame.len)) {
1667         return ERROR_MALFORMED;
1668     }
1669 
1670     // Override the synthesized nal length size, which is arbitrary
1671     trackInfo->mNalLengthSize = 0;
1672     return OK;
1673 }
1674 
synthesizeMPEG2(TrackInfo * trackInfo,size_t index)1675 status_t MatroskaExtractor::synthesizeMPEG2(TrackInfo *trackInfo, size_t index) {
1676     ALOGV("synthesizeMPEG2");
1677     BlockIterator iter(this, trackInfo->mTrackNum, index);
1678     if (iter.eos()) {
1679         return ERROR_MALFORMED;
1680     }
1681 
1682     const mkvparser::Block *block = iter.block();
1683     if (block->GetFrameCount() <= 0) {
1684         return ERROR_MALFORMED;
1685     }
1686 
1687     const mkvparser::Block::Frame &frame = block->GetFrame(0);
1688     auto tmpData = heapbuffer<unsigned char>(frame.len);
1689     long n = frame.Read(mReader, tmpData.get());
1690     if (n != 0) {
1691         return ERROR_MALFORMED;
1692     }
1693 
1694     size_t header_start = 0;
1695     size_t header_lenth = 0;
1696     for (header_start = 0; header_start < frame.len - 4; header_start++) {
1697         if (ntohl(0x000001b3) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start)) {
1698             break;
1699         }
1700     }
1701     bool isComplete_csd = false;
1702     for (header_lenth = 0; header_lenth < frame.len - 4 - header_start; header_lenth++) {
1703         if (ntohl(0x000001b8) == *(uint32_t*)((uint8_t*)tmpData.get()
1704                                 + header_start + header_lenth)) {
1705             isComplete_csd = true;
1706             break;
1707         }
1708     }
1709     if (!isComplete_csd) {
1710         ALOGE("can't parse complete csd for MPEG2!");
1711         return ERROR_MALFORMED;
1712     }
1713     addESDSFromCodecPrivate(trackInfo->mMeta, false,
1714                               (uint8_t*)(tmpData.get()) + header_start, header_lenth);
1715 
1716     return OK;
1717 
1718 }
1719 
synthesizeMPEG4(TrackInfo * trackInfo,size_t index)1720 status_t MatroskaExtractor::synthesizeMPEG4(TrackInfo *trackInfo, size_t index) {
1721     ALOGV("synthesizeMPEG4");
1722     BlockIterator iter(this, trackInfo->mTrackNum, index);
1723     if (iter.eos()) {
1724         return ERROR_MALFORMED;
1725     }
1726 
1727     const mkvparser::Block *block = iter.block();
1728     if (block->GetFrameCount() <= 0) {
1729         return ERROR_MALFORMED;
1730     }
1731 
1732     const mkvparser::Block::Frame &frame = block->GetFrame(0);
1733     auto tmpData = heapbuffer<unsigned char>(frame.len);
1734     long n = frame.Read(mReader, tmpData.get());
1735     if (n != 0) {
1736         return ERROR_MALFORMED;
1737     }
1738 
1739      size_t vosend;
1740      bool isComplete_csd = false;
1741      for (vosend = 0; (long)vosend < frame.len - 4; vosend++) {
1742          if (ntohl(0x000001b6) == *(uint32_t*)((uint8_t*)tmpData.get() + vosend)) {
1743              isComplete_csd = true;
1744              break;  // Send VOS until VOP
1745          }
1746      }
1747      if (!isComplete_csd) {
1748          ALOGE("can't parse complete csd for MPEG4!");
1749          return ERROR_MALFORMED;
1750      }
1751      addESDSFromCodecPrivate(trackInfo->mMeta, false, tmpData.get(), vosend);
1752 
1753     return OK;
1754 
1755 }
1756 
1757 
isValidInt32ColourValue(long long value)1758 static inline bool isValidInt32ColourValue(long long value) {
1759     return value != mkvparser::Colour::kValueNotPresent
1760             && value >= INT32_MIN
1761             && value <= INT32_MAX;
1762 }
1763 
isValidUint16ColourValue(long long value)1764 static inline bool isValidUint16ColourValue(long long value) {
1765     return value != mkvparser::Colour::kValueNotPresent
1766             && value >= 0
1767             && value <= UINT16_MAX;
1768 }
1769 
isValidPrimary(const mkvparser::PrimaryChromaticity * primary)1770 static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) {
1771     return primary != NULL && primary->x >= 0 && primary->x <= 1
1772              && primary->y >= 0 && primary->y <= 1;
1773 }
1774 
getColorInformation(const mkvparser::VideoTrack * vtrack,AMediaFormat * meta)1775 void MatroskaExtractor::getColorInformation(
1776         const mkvparser::VideoTrack *vtrack, AMediaFormat *meta) {
1777     const mkvparser::Colour *color = vtrack->GetColour();
1778     if (color == NULL) {
1779         return;
1780     }
1781 
1782     // Color Aspects
1783     {
1784         int32_t primaries = 2; // ISO unspecified
1785         int32_t isotransfer = 2; // ISO unspecified
1786         int32_t coeffs = 2; // ISO unspecified
1787         bool fullRange = false; // default
1788         bool rangeSpecified = false;
1789 
1790         if (isValidInt32ColourValue(color->primaries)) {
1791             primaries = color->primaries;
1792         }
1793         if (isValidInt32ColourValue(color->transfer_characteristics)) {
1794             isotransfer = color->transfer_characteristics;
1795         }
1796         if (isValidInt32ColourValue(color->matrix_coefficients)) {
1797             coeffs = color->matrix_coefficients;
1798         }
1799         if (color->range != mkvparser::Colour::kValueNotPresent
1800                 && color->range != 0 /* MKV unspecified */) {
1801             // We only support MKV broadcast range (== limited) and full range.
1802             // We treat all other value as the default limited range.
1803             fullRange = color->range == 2 /* MKV fullRange */;
1804             rangeSpecified = true;
1805         }
1806 
1807         int32_t range = 0;
1808         int32_t standard = 0;
1809         int32_t transfer = 0;
1810         ColorUtils::convertIsoColorAspectsToPlatformAspects(
1811                 primaries, isotransfer, coeffs, fullRange,
1812                 &range, &standard, &transfer);
1813         if (range != 0) {
1814             AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_RANGE, range);
1815         }
1816         if (standard != 0) {
1817             AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_STANDARD, standard);
1818         }
1819         if (transfer != 0) {
1820             AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_TRANSFER, transfer);
1821         }
1822     }
1823 
1824     // HDR Static Info
1825     {
1826         HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info
1827         memset(&info, 0, sizeof(info));
1828         memset(&nullInfo, 0, sizeof(nullInfo));
1829         if (isValidUint16ColourValue(color->max_cll)) {
1830             info.sType1.mMaxContentLightLevel = color->max_cll;
1831         }
1832         if (isValidUint16ColourValue(color->max_fall)) {
1833             info.sType1.mMaxFrameAverageLightLevel = color->max_fall;
1834         }
1835         const mkvparser::MasteringMetadata *mastering = color->mastering_metadata;
1836         if (mastering != NULL) {
1837             // Convert matroska values to HDRStaticInfo equivalent values for each fully specified
1838             // group. See CTA-681.3 section 3.2.1 for more info.
1839             if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) {
1840                 info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5);
1841             }
1842             if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) {
1843                 // HDRStaticInfo Type1 stores min luminance scaled 10000:1
1844                 info.sType1.mMinDisplayLuminance =
1845                     (uint16_t)(10000 * mastering->luminance_min + 0.5);
1846             }
1847             // HDRStaticInfo Type1 stores primaries scaled 50000:1
1848             if (isValidPrimary(mastering->white_point)) {
1849                 info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5);
1850                 info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5);
1851             }
1852             if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g)
1853                     && isValidPrimary(mastering->b)) {
1854                 info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5);
1855                 info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5);
1856                 info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5);
1857                 info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5);
1858                 info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5);
1859                 info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5);
1860             }
1861         }
1862         // Only advertise static info if at least one of the groups have been specified.
1863         if (memcmp(&info, &nullInfo, sizeof(info)) != 0) {
1864             info.mID = HDRStaticInfo::kType1;
1865             ColorUtils::setHDRStaticInfoIntoAMediaFormat(info, meta);
1866         }
1867     }
1868 }
1869 
initTrackInfo(const mkvparser::Track * track,AMediaFormat * meta,TrackInfo * trackInfo)1870 status_t MatroskaExtractor::initTrackInfo(
1871         const mkvparser::Track *track, AMediaFormat *meta, TrackInfo *trackInfo) {
1872     trackInfo->mTrackNum = track->GetNumber();
1873     trackInfo->mMeta = meta;
1874     trackInfo->mExtractor = this;
1875     trackInfo->mEncrypted = false;
1876     trackInfo->mHeader = NULL;
1877     trackInfo->mHeaderLen = 0;
1878     trackInfo->mNalLengthSize = -1;
1879 
1880     for(size_t i = 0; i < track->GetContentEncodingCount(); i++) {
1881         const mkvparser::ContentEncoding *encoding = track->GetContentEncodingByIndex(i);
1882         if (encoding->GetEncryptionCount() > 0) {
1883             const mkvparser::ContentEncoding::ContentEncryption *encryption;
1884             encryption = encoding->GetEncryptionByIndex(0);
1885             AMediaFormat_setBuffer(trackInfo->mMeta,
1886                     AMEDIAFORMAT_KEY_CRYPTO_KEY, encryption->key_id, encryption->key_id_len);
1887             trackInfo->mEncrypted = true;
1888         }
1889 
1890         for(size_t j = 0; j < encoding->GetCompressionCount(); j++) {
1891             const mkvparser::ContentEncoding::ContentCompression *compression;
1892             compression = encoding->GetCompressionByIndex(j);
1893             ALOGV("compression algo %llu settings_len %lld",
1894                 compression->algo, compression->settings_len);
1895             if (compression->algo == 3
1896                     && compression->settings
1897                     && compression->settings_len > 0) {
1898                 trackInfo->mHeader = compression->settings;
1899                 trackInfo->mHeaderLen = compression->settings_len;
1900             }
1901         }
1902     }
1903 
1904     return OK;
1905 }
1906 
addTracks()1907 void MatroskaExtractor::addTracks() {
1908     const mkvparser::Tracks *tracks = mSegment->GetTracks();
1909 
1910     AMediaFormat *meta = nullptr;
1911 
1912     for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
1913         const mkvparser::Track *track = tracks->GetTrackByIndex(index);
1914 
1915         if (track == NULL) {
1916             // Apparently this is currently valid (if unexpected) behaviour
1917             // of the mkv parser lib.
1918             continue;
1919         }
1920 
1921         const char *const codecID = track->GetCodecId();
1922         ALOGV("codec id = %s", codecID);
1923         ALOGV("codec name = %s", track->GetCodecNameAsUTF8());
1924 
1925         if (codecID == NULL) {
1926             ALOGW("unknown codecID is not supported.");
1927             continue;
1928         }
1929 
1930         size_t codecPrivateSize;
1931         const unsigned char *codecPrivate =
1932             track->GetCodecPrivate(codecPrivateSize);
1933 
1934         enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
1935 
1936         if (meta) {
1937             AMediaFormat_clear(meta);
1938         } else {
1939             meta = AMediaFormat_new();
1940         }
1941 
1942         status_t err = OK;
1943         int32_t nalSize = -1;
1944 
1945         bool isSetCsdFrom1stFrame = false;
1946 
1947         switch (track->GetType()) {
1948             case VIDEO_TRACK:
1949             {
1950                 const mkvparser::VideoTrack *vtrack =
1951                     static_cast<const mkvparser::VideoTrack *>(track);
1952 
1953                 if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
1954                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
1955                     AMediaFormat_setBuffer(meta,
1956                            AMEDIAFORMAT_KEY_CSD_AVC, codecPrivate, codecPrivateSize);
1957                     if (codecPrivateSize > 4) {
1958                         nalSize = 1 + (codecPrivate[4] & 3);
1959                     }
1960                 } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) {
1961                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_HEVC);
1962                     if (codecPrivateSize > 0) {
1963                         AMediaFormat_setBuffer(meta,
1964                                AMEDIAFORMAT_KEY_CSD_HEVC, codecPrivate, codecPrivateSize);
1965                         if (codecPrivateSize > 14 + 7) {
1966                             nalSize = 1 + (codecPrivate[14 + 7] & 3);
1967                         }
1968                     } else {
1969                         ALOGW("HEVC is detected, but does not have configuration.");
1970                         continue;
1971                     }
1972                 } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
1973                     AMediaFormat_setString(meta,
1974                             AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4);
1975                     if (codecPrivateSize > 0) {
1976                         addESDSFromCodecPrivate(
1977                                 meta, false, codecPrivate, codecPrivateSize);
1978                     } else {
1979                         ALOGW("%s is detected, but does not have configuration.",
1980                                 codecID);
1981                         isSetCsdFrom1stFrame = true;
1982                     }
1983                 } else if (!strcmp("V_VP8", codecID)) {
1984                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8);
1985                 } else if (!strcmp("V_VP9", codecID)) {
1986                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP9);
1987                     if (codecPrivateSize > 0) {
1988                       // 'csd-0' for VP9 is the Blob of Codec Private data as
1989                       // specified in http://www.webmproject.org/vp9/profiles/.
1990                       AMediaFormat_setBuffer(meta,
1991                              AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
1992                     }
1993                 } else if (!strcmp("V_AV1", codecID)) {
1994                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
1995                     if (codecPrivateSize > 0) {
1996                         // 'csd-0' for AV1 is the Blob of Codec Private data as
1997                         // specified in https://aomediacodec.github.io/av1-isobmff/.
1998                         AMediaFormat_setBuffer(
1999                                 meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
2000                     }
2001                 } else if (!strcmp("V_MPEG2", codecID) || !strcmp("V_MPEG1", codecID)) {
2002                         AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
2003                                 MEDIA_MIMETYPE_VIDEO_MPEG2);
2004                         if (codecPrivate != NULL) {
2005                             addESDSFromCodecPrivate(meta, false, codecPrivate, codecPrivateSize);
2006                         } else {
2007                             ALOGW("No specific codec private data, find it from the first frame");
2008                             isSetCsdFrom1stFrame = true;
2009                         }
2010                 } else if (!strcmp("V_MJPEG", codecID)) {
2011                         AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
2012                                 MEDIA_MIMETYPE_VIDEO_MJPEG);
2013                 } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) {
2014                     if (NULL == codecPrivate ||codecPrivateSize < 20) {
2015                         ALOGE("V_MS/VFW/FOURCC has no valid private data(%p),codecPrivateSize:%zu",
2016                                  codecPrivate, codecPrivateSize);
2017                         continue;
2018                     } else {
2019                         uint32_t fourcc = *(uint32_t *)(codecPrivate + 16);
2020                         fourcc = ntohl(fourcc);
2021                         const char* mime = MKVFourCC2MIME(fourcc);
2022                         ALOGV("V_MS/VFW/FOURCC type is %s", mime);
2023                         if (!strncasecmp("video/", mime, 6)) {
2024                             AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime);
2025                         } else {
2026                             ALOGE("V_MS/VFW/FOURCC continue,unsupport video type=%s,fourcc=0x%08x.",
2027                                  mime, fourcc);
2028                             continue;
2029                         }
2030                         if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) ||
2031                             !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
2032                             !strcmp(mime, MEDIA_MIMETYPE_VIDEO_XVID) ||
2033                             !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX) ||
2034                             !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX3) ||
2035                             !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) ||
2036                             !strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
2037                             isSetCsdFrom1stFrame = true;
2038                         } else {
2039                             ALOGW("FourCC have unsupport codec, type=%s,fourcc=0x%08x.",
2040                                   mime, fourcc);
2041                             continue;
2042                         }
2043                     }
2044                 } else {
2045                     ALOGW("%s is not supported.", codecID);
2046                     continue;
2047                 }
2048 
2049                 const long long width = vtrack->GetWidth();
2050                 const long long height = vtrack->GetHeight();
2051                 if (width <= 0 || width > INT32_MAX) {
2052                     ALOGW("track width exceeds int32_t, %lld", width);
2053                     continue;
2054                 }
2055                 if (height <= 0 || height > INT32_MAX) {
2056                     ALOGW("track height exceeds int32_t, %lld", height);
2057                     continue;
2058                 }
2059                 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, (int32_t)width);
2060                 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, (int32_t)height);
2061 
2062                 // setting display width/height is optional
2063                 const long long displayUnit = vtrack->GetDisplayUnit();
2064                 const long long displayWidth = vtrack->GetDisplayWidth();
2065                 const long long displayHeight = vtrack->GetDisplayHeight();
2066                 if (displayWidth > 0 && displayWidth <= INT32_MAX
2067                         && displayHeight > 0 && displayHeight <= INT32_MAX) {
2068                     switch (displayUnit) {
2069                     case 0: // pixels
2070                         AMediaFormat_setInt32(meta,
2071                                 AMEDIAFORMAT_KEY_DISPLAY_WIDTH, (int32_t)displayWidth);
2072                         AMediaFormat_setInt32(meta,
2073                                 AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, (int32_t)displayHeight);
2074                         break;
2075                     case 1: // centimeters
2076                     case 2: // inches
2077                     case 3: // aspect ratio
2078                     {
2079                         // Physical layout size is treated the same as aspect ratio.
2080                         // Note: displayWidth and displayHeight are never zero as they are
2081                         // checked in the if above.
2082                         const long long computedWidth =
2083                                 std::max(width, height * displayWidth / displayHeight);
2084                         const long long computedHeight =
2085                                 std::max(height, width * displayHeight / displayWidth);
2086                         if (computedWidth <= INT32_MAX && computedHeight <= INT32_MAX) {
2087                             AMediaFormat_setInt32(meta,
2088                                     AMEDIAFORMAT_KEY_DISPLAY_WIDTH, (int32_t)computedWidth);
2089                             AMediaFormat_setInt32(meta,
2090                                     AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, (int32_t)computedHeight);
2091                         }
2092                         break;
2093                     }
2094                     default: // unknown display units, perhaps future version of spec.
2095                         break;
2096                     }
2097                 }
2098 
2099                 getColorInformation(vtrack, meta);
2100 
2101                 break;
2102             }
2103 
2104             case AUDIO_TRACK:
2105             {
2106                 const mkvparser::AudioTrack *atrack =
2107                     static_cast<const mkvparser::AudioTrack *>(track);
2108 
2109                 if (!strcmp("A_AAC", codecID)) {
2110                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
2111                     if (codecPrivateSize < 2) {
2112                         ALOGW("Incomplete AAC Codec Info %zu byte", codecPrivateSize);
2113                         continue;
2114                     }
2115                     addESDSFromCodecPrivate(
2116                             meta, true, codecPrivate, codecPrivateSize);
2117                 } else if (!strcmp("A_VORBIS", codecID)) {
2118                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_VORBIS);
2119 
2120                     err = addVorbisCodecInfo(
2121                             meta, codecPrivate, codecPrivateSize);
2122                 } else if (!strcmp("A_OPUS", codecID)) {
2123                     AMediaFormat_setString(meta,
2124                             AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_OPUS);
2125                     AMediaFormat_setBuffer(meta,
2126                             AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
2127                     int64_t codecDelay = track->GetCodecDelay();
2128                     AMediaFormat_setBuffer(meta,
2129                             AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
2130                     mSeekPreRollNs = track->GetSeekPreRoll();
2131                     AMediaFormat_setBuffer(meta,
2132                             AMEDIAFORMAT_KEY_CSD_2, &mSeekPreRollNs, sizeof(mSeekPreRollNs));
2133                 } else if (!strcmp("A_MPEG/L3", codecID)) {
2134                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
2135                 } else if (!strcmp("A_FLAC", codecID)) {
2136                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
2137                     err = addFlacMetadata(meta, codecPrivate, codecPrivateSize);
2138                 } else if (!strcmp("A_MPEG/L2", codecID)) {
2139                     AMediaFormat_setString(meta,
2140                             AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
2141                 } else if (!strcmp("A_PCM/INT/LIT", codecID) ||
2142                          !strcmp("A_PCM/INT/BIG", codecID)) {
2143                     AMediaFormat_setString(meta,
2144                             AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
2145                     int32_t bigEndian = !strcmp("A_PCM/INT/BIG", codecID) ? 1: 0;
2146                     AMediaFormat_setInt32(meta,
2147                             AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, bigEndian);
2148                 } else if ((!strcmp("A_MS/ACM", codecID))) {
2149                     if ((NULL == codecPrivate) || (codecPrivateSize < 18)) {
2150                         ALOGW("unsupported audio: A_MS/ACM has no valid private data: %s, size: %zu",
2151                                codecPrivate == NULL ? "null" : "non-null", codecPrivateSize);
2152                         continue;
2153                     } else {
2154                         uint16_t ID = *(uint16_t *)codecPrivate;
2155                         const char* mime = MKVWave2MIME(ID);
2156                         ALOGV("A_MS/ACM type is %s", mime);
2157                         if (!strncasecmp("audio/", mime, 6) &&
2158                                 isMkvAudioCsdSizeOK(mime, codecPrivateSize)) {
2159                             AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime);
2160                         } else {
2161                             ALOGE("A_MS/ACM continue, unsupported audio type=%s, csdSize:%zu",
2162                                 mime, codecPrivateSize);
2163                             continue;
2164                         }
2165                         if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_WMA)) {
2166                             addESDSFromCodecPrivate(meta, true, codecPrivate, codecPrivateSize);
2167                         } else if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MS_ADPCM) ||
2168                                     !strcmp(mime, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM)) {
2169                             uint32_t blockAlign = *(uint16_t*)(codecPrivate + 12);
2170                             addESDSFromCodecPrivate(meta, true, &blockAlign, sizeof(blockAlign));
2171                         }
2172                     }
2173                 } else {
2174                     ALOGW("%s is not supported.", codecID);
2175                     continue;
2176                 }
2177 
2178                 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, atrack->GetSamplingRate());
2179                 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, atrack->GetChannels());
2180                 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, atrack->GetBitDepth());
2181                 break;
2182             }
2183 
2184             default:
2185                 continue;
2186         }
2187 
2188         const char *language = track->GetLanguage();
2189         if (language != NULL) {
2190            char lang[4];
2191            strncpy(lang, language, 3);
2192            lang[3] = '\0';
2193            AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_LANGUAGE, lang);
2194         }
2195 
2196         if (err != OK) {
2197             ALOGE("skipping track, codec specific data was malformed.");
2198             continue;
2199         }
2200 
2201         long long durationNs = mSegment->GetDuration();
2202         AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_DURATION, (durationNs + 500) / 1000);
2203 
2204         const char *mimetype = "";
2205         if (!AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype)) {
2206             // do not add this track to the track list
2207             ALOGW("ignoring track with unknown mime");
2208             continue;
2209         }
2210 
2211         mTracks.push();
2212         size_t n = mTracks.size() - 1;
2213         TrackInfo *trackInfo = &mTracks.editItemAt(n);
2214         initTrackInfo(track, meta, trackInfo);
2215         trackInfo->mNalLengthSize = nalSize;
2216 
2217         if ((!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) ||
2218             (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_AVC) && isSetCsdFrom1stFrame)) {
2219             // Attempt to recover from AVC track without codec private data
2220             err = synthesizeAVCC(trackInfo, n);
2221             if (err != OK) {
2222                 mTracks.pop();
2223                 continue;
2224             }
2225         } else if ((!strcmp("V_MPEG2", codecID) && codecPrivateSize == 0) ||
2226             (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG2) && isSetCsdFrom1stFrame)) {
2227             // Attempt to recover from MPEG2 track without codec private data
2228             err = synthesizeMPEG2(trackInfo, n);
2229             if (err != OK) {
2230                 mTracks.pop();
2231                 continue;
2232             }
2233         } else if ((!strcmp("V_MPEG4/ISO/ASP", codecID) && codecPrivateSize == 0) ||
2234             (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG4) && isSetCsdFrom1stFrame) ||
2235             (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_XVID) && isSetCsdFrom1stFrame) ||
2236             (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX) && isSetCsdFrom1stFrame) ||
2237             (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX3) && isSetCsdFrom1stFrame)) {
2238             // Attempt to recover from MPEG4 track without codec private data
2239             err = synthesizeMPEG4(trackInfo, n);
2240             if (err != OK) {
2241                 mTracks.pop();
2242                 continue;
2243             }
2244         }
2245         // the TrackInfo owns the metadata now
2246         meta = nullptr;
2247     }
2248     if (meta) {
2249         AMediaFormat_delete(meta);
2250     }
2251 }
2252 
findThumbnails()2253 void MatroskaExtractor::findThumbnails() {
2254     for (size_t i = 0; i < mTracks.size(); ++i) {
2255         TrackInfo *info = &mTracks.editItemAt(i);
2256 
2257         const char *mime;
2258         CHECK(AMediaFormat_getString(info->mMeta, AMEDIAFORMAT_KEY_MIME, &mime));
2259 
2260         if (strncasecmp(mime, "video/", 6)) {
2261             continue;
2262         }
2263 
2264         BlockIterator iter(this, info->mTrackNum, i);
2265         int32_t j = 0;
2266         int64_t thumbnailTimeUs = 0;
2267         size_t maxBlockSize = 0;
2268         while (!iter.eos() && j < 20) {
2269             if (iter.block()->IsKey()) {
2270                 ++j;
2271 
2272                 size_t blockSize = 0;
2273                 for (int k = 0; k < iter.block()->GetFrameCount(); ++k) {
2274                     blockSize += iter.block()->GetFrame(k).len;
2275                 }
2276 
2277                 if (blockSize > maxBlockSize) {
2278                     maxBlockSize = blockSize;
2279                     thumbnailTimeUs = iter.blockTimeUs();
2280                 }
2281             }
2282             iter.advance();
2283         }
2284         AMediaFormat_setInt64(info->mMeta,
2285                 AMEDIAFORMAT_KEY_THUMBNAIL_TIME, thumbnailTimeUs);
2286     }
2287 }
2288 
getMetaData(AMediaFormat * meta)2289 media_status_t MatroskaExtractor::getMetaData(AMediaFormat *meta) {
2290     AMediaFormat_setString(meta,
2291             AMEDIAFORMAT_KEY_MIME, mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA);
2292 
2293     return AMEDIA_OK;
2294 }
2295 
flags() const2296 uint32_t MatroskaExtractor::flags() const {
2297     uint32_t x = CAN_PAUSE;
2298     if (!isLiveStreaming()) {
2299         x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
2300     }
2301 
2302     return x;
2303 }
2304 
SniffMatroska(DataSourceHelper * source,float * confidence)2305 bool SniffMatroska(
2306         DataSourceHelper *source, float *confidence) {
2307     DataSourceBaseReader reader(source);
2308     mkvparser::EBMLHeader ebmlHeader;
2309     long long pos;
2310     if (ebmlHeader.Parse(&reader, pos) < 0) {
2311         return false;
2312     }
2313 
2314     *confidence = 0.6;
2315 
2316     return true;
2317 }
2318 
2319 static const char *extensions[] = {
2320     "mka",
2321     "mkv",
2322     "webm",
2323     NULL
2324 };
2325 
2326 extern "C" {
2327 // This is the only symbol that needs to be exported
2328 __attribute__ ((visibility ("default")))
GETEXTRACTORDEF()2329 ExtractorDef GETEXTRACTORDEF() {
2330     return {
2331         EXTRACTORDEF_VERSION,
2332         UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"),
2333         1,
2334         "Matroska Extractor",
2335         {
2336             .v3 = {
2337                 [](
2338                     CDataSource *source,
2339                     float *confidence,
2340                     void **,
2341                     FreeMetaFunc *) -> CreatorFunc {
2342                     DataSourceHelper helper(source);
2343                     if (SniffMatroska(&helper, confidence)) {
2344                         return [](
2345                                 CDataSource *source,
2346                                 void *) -> CMediaExtractor* {
2347                             return wrap(new MatroskaExtractor(new DataSourceHelper(source)));};
2348                     }
2349                     return NULL;
2350                 },
2351                 extensions
2352             }
2353         }
2354     };
2355 }
2356 
2357 } // extern "C"
2358 
2359 }  // namespace android
2360