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