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