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