1 /*
2 * Copyright (C) 2009 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 "MPEG4Extractor"
19
20 #include <ctype.h>
21 #include <inttypes.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <utils/Log.h>
27
28 #include "include/MPEG4Extractor.h"
29 #include "include/SampleTable.h"
30 #include "include/ESDS.h"
31
32 #include <media/stagefright/foundation/ABitReader.h>
33 #include <media/stagefright/foundation/ABuffer.h>
34 #include <media/stagefright/foundation/ADebug.h>
35 #include <media/stagefright/foundation/AMessage.h>
36 #include <media/stagefright/foundation/AUtils.h>
37 #include <media/stagefright/foundation/ColorUtils.h>
38 #include <media/stagefright/MediaBuffer.h>
39 #include <media/stagefright/MediaBufferGroup.h>
40 #include <media/stagefright/MediaDefs.h>
41 #include <media/stagefright/MediaSource.h>
42 #include <media/stagefright/MetaData.h>
43 #include <utils/String8.h>
44
45 #include <byteswap.h>
46 #include "include/ID3.h"
47 #include "include/avc_utils.h"
48
49 #ifndef UINT32_MAX
50 #define UINT32_MAX (4294967295U)
51 #endif
52
53 namespace android {
54
55 enum {
56 // max track header chunk to return
57 kMaxTrackHeaderSize = 32,
58
59 // maximum size of an atom. Some atoms can be bigger according to the spec,
60 // but we only allow up to this size.
61 kMaxAtomSize = 64 * 1024 * 1024,
62 };
63
64 class MPEG4Source : public MediaSource {
65 public:
66 // Caller retains ownership of both "dataSource" and "sampleTable".
67 MPEG4Source(const sp<MPEG4Extractor> &owner,
68 const sp<MetaData> &format,
69 const sp<DataSource> &dataSource,
70 int32_t timeScale,
71 const sp<SampleTable> &sampleTable,
72 Vector<SidxEntry> &sidx,
73 const Trex *trex,
74 off64_t firstMoofOffset);
75 virtual status_t init();
76
77 virtual status_t start(MetaData *params = NULL);
78 virtual status_t stop();
79
80 virtual sp<MetaData> getFormat();
81
82 virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
supportNonblockingRead()83 virtual bool supportNonblockingRead() { return true; }
84 virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL);
85
86 protected:
87 virtual ~MPEG4Source();
88
89 private:
90 Mutex mLock;
91
92 // keep the MPEG4Extractor around, since we're referencing its data
93 sp<MPEG4Extractor> mOwner;
94 sp<MetaData> mFormat;
95 sp<DataSource> mDataSource;
96 int32_t mTimescale;
97 sp<SampleTable> mSampleTable;
98 uint32_t mCurrentSampleIndex;
99 uint32_t mCurrentFragmentIndex;
100 Vector<SidxEntry> &mSegments;
101 const Trex *mTrex;
102 off64_t mFirstMoofOffset;
103 off64_t mCurrentMoofOffset;
104 off64_t mNextMoofOffset;
105 uint32_t mCurrentTime;
106 int32_t mLastParsedTrackId;
107 int32_t mTrackId;
108
109 int32_t mCryptoMode; // passed in from extractor
110 int32_t mDefaultIVSize; // passed in from extractor
111 uint8_t mCryptoKey[16]; // passed in from extractor
112 uint32_t mCurrentAuxInfoType;
113 uint32_t mCurrentAuxInfoTypeParameter;
114 int32_t mCurrentDefaultSampleInfoSize;
115 uint32_t mCurrentSampleInfoCount;
116 uint32_t mCurrentSampleInfoAllocSize;
117 uint8_t* mCurrentSampleInfoSizes;
118 uint32_t mCurrentSampleInfoOffsetCount;
119 uint32_t mCurrentSampleInfoOffsetsAllocSize;
120 uint64_t* mCurrentSampleInfoOffsets;
121
122 bool mIsAVC;
123 bool mIsHEVC;
124 size_t mNALLengthSize;
125
126 bool mStarted;
127
128 MediaBufferGroup *mGroup;
129
130 MediaBuffer *mBuffer;
131
132 bool mWantsNALFragments;
133
134 uint8_t *mSrcBuffer;
135
136 size_t parseNALSize(const uint8_t *data) const;
137 status_t parseChunk(off64_t *offset);
138 status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
139 status_t parseTrackFragmentRun(off64_t offset, off64_t size);
140 status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
141 status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
142
143 struct TrackFragmentHeaderInfo {
144 enum Flags {
145 kBaseDataOffsetPresent = 0x01,
146 kSampleDescriptionIndexPresent = 0x02,
147 kDefaultSampleDurationPresent = 0x08,
148 kDefaultSampleSizePresent = 0x10,
149 kDefaultSampleFlagsPresent = 0x20,
150 kDurationIsEmpty = 0x10000,
151 };
152
153 uint32_t mTrackID;
154 uint32_t mFlags;
155 uint64_t mBaseDataOffset;
156 uint32_t mSampleDescriptionIndex;
157 uint32_t mDefaultSampleDuration;
158 uint32_t mDefaultSampleSize;
159 uint32_t mDefaultSampleFlags;
160
161 uint64_t mDataOffset;
162 };
163 TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
164
165 struct Sample {
166 off64_t offset;
167 size_t size;
168 uint32_t duration;
169 int32_t compositionOffset;
170 uint8_t iv[16];
171 Vector<size_t> clearsizes;
172 Vector<size_t> encryptedsizes;
173 };
174 Vector<Sample> mCurrentSamples;
175
176 MPEG4Source(const MPEG4Source &);
177 MPEG4Source &operator=(const MPEG4Source &);
178 };
179
180 // This custom data source wraps an existing one and satisfies requests
181 // falling entirely within a cached range from the cache while forwarding
182 // all remaining requests to the wrapped datasource.
183 // This is used to cache the full sampletable metadata for a single track,
184 // possibly wrapping multiple times to cover all tracks, i.e.
185 // Each MPEG4DataSource caches the sampletable metadata for a single track.
186
187 struct MPEG4DataSource : public DataSource {
188 explicit MPEG4DataSource(const sp<DataSource> &source);
189
190 virtual status_t initCheck() const;
191 virtual ssize_t readAt(off64_t offset, void *data, size_t size);
192 virtual status_t getSize(off64_t *size);
193 virtual uint32_t flags();
194
195 status_t setCachedRange(off64_t offset, size_t size);
196
197 protected:
198 virtual ~MPEG4DataSource();
199
200 private:
201 Mutex mLock;
202
203 sp<DataSource> mSource;
204 off64_t mCachedOffset;
205 size_t mCachedSize;
206 uint8_t *mCache;
207
208 void clearCache();
209
210 MPEG4DataSource(const MPEG4DataSource &);
211 MPEG4DataSource &operator=(const MPEG4DataSource &);
212 };
213
MPEG4DataSource(const sp<DataSource> & source)214 MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
215 : mSource(source),
216 mCachedOffset(0),
217 mCachedSize(0),
218 mCache(NULL) {
219 }
220
~MPEG4DataSource()221 MPEG4DataSource::~MPEG4DataSource() {
222 clearCache();
223 }
224
clearCache()225 void MPEG4DataSource::clearCache() {
226 if (mCache) {
227 free(mCache);
228 mCache = NULL;
229 }
230
231 mCachedOffset = 0;
232 mCachedSize = 0;
233 }
234
initCheck() const235 status_t MPEG4DataSource::initCheck() const {
236 return mSource->initCheck();
237 }
238
readAt(off64_t offset,void * data,size_t size)239 ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
240 Mutex::Autolock autoLock(mLock);
241
242 if (isInRange(mCachedOffset, mCachedSize, offset, size)) {
243 memcpy(data, &mCache[offset - mCachedOffset], size);
244 return size;
245 }
246
247 return mSource->readAt(offset, data, size);
248 }
249
getSize(off64_t * size)250 status_t MPEG4DataSource::getSize(off64_t *size) {
251 return mSource->getSize(size);
252 }
253
flags()254 uint32_t MPEG4DataSource::flags() {
255 return mSource->flags();
256 }
257
setCachedRange(off64_t offset,size_t size)258 status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) {
259 Mutex::Autolock autoLock(mLock);
260
261 clearCache();
262
263 mCache = (uint8_t *)malloc(size);
264
265 if (mCache == NULL) {
266 return -ENOMEM;
267 }
268
269 mCachedOffset = offset;
270 mCachedSize = size;
271
272 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
273
274 if (err < (ssize_t)size) {
275 clearCache();
276
277 return ERROR_IO;
278 }
279
280 return OK;
281 }
282
283 ////////////////////////////////////////////////////////////////////////////////
284
285 static const bool kUseHexDump = false;
286
hexdump(const void * _data,size_t size)287 static void hexdump(const void *_data, size_t size) {
288 const uint8_t *data = (const uint8_t *)_data;
289 size_t offset = 0;
290 while (offset < size) {
291 printf("0x%04zx ", offset);
292
293 size_t n = size - offset;
294 if (n > 16) {
295 n = 16;
296 }
297
298 for (size_t i = 0; i < 16; ++i) {
299 if (i == 8) {
300 printf(" ");
301 }
302
303 if (offset + i < size) {
304 printf("%02x ", data[offset + i]);
305 } else {
306 printf(" ");
307 }
308 }
309
310 printf(" ");
311
312 for (size_t i = 0; i < n; ++i) {
313 if (isprint(data[offset + i])) {
314 printf("%c", data[offset + i]);
315 } else {
316 printf(".");
317 }
318 }
319
320 printf("\n");
321
322 offset += 16;
323 }
324 }
325
FourCC2MIME(uint32_t fourcc)326 static const char *FourCC2MIME(uint32_t fourcc) {
327 switch (fourcc) {
328 case FOURCC('m', 'p', '4', 'a'):
329 return MEDIA_MIMETYPE_AUDIO_AAC;
330
331 case FOURCC('s', 'a', 'm', 'r'):
332 return MEDIA_MIMETYPE_AUDIO_AMR_NB;
333
334 case FOURCC('s', 'a', 'w', 'b'):
335 return MEDIA_MIMETYPE_AUDIO_AMR_WB;
336
337 case FOURCC('m', 'p', '4', 'v'):
338 return MEDIA_MIMETYPE_VIDEO_MPEG4;
339
340 case FOURCC('s', '2', '6', '3'):
341 case FOURCC('h', '2', '6', '3'):
342 case FOURCC('H', '2', '6', '3'):
343 return MEDIA_MIMETYPE_VIDEO_H263;
344
345 case FOURCC('a', 'v', 'c', '1'):
346 return MEDIA_MIMETYPE_VIDEO_AVC;
347
348 case FOURCC('h', 'v', 'c', '1'):
349 case FOURCC('h', 'e', 'v', '1'):
350 return MEDIA_MIMETYPE_VIDEO_HEVC;
351 default:
352 CHECK(!"should not be here.");
353 return NULL;
354 }
355 }
356
AdjustChannelsAndRate(uint32_t fourcc,uint32_t * channels,uint32_t * rate)357 static bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) {
358 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) {
359 // AMR NB audio is always mono, 8kHz
360 *channels = 1;
361 *rate = 8000;
362 return true;
363 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) {
364 // AMR WB audio is always mono, 16kHz
365 *channels = 1;
366 *rate = 16000;
367 return true;
368 }
369 return false;
370 }
371
MPEG4Extractor(const sp<DataSource> & source)372 MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
373 : mMoofOffset(0),
374 mMoofFound(false),
375 mMdatFound(false),
376 mDataSource(source),
377 mInitCheck(NO_INIT),
378 mHeaderTimescale(0),
379 mIsQT(false),
380 mFirstTrack(NULL),
381 mLastTrack(NULL),
382 mFileMetaData(new MetaData),
383 mFirstSINF(NULL),
384 mIsDrm(false) {
385 }
386
~MPEG4Extractor()387 MPEG4Extractor::~MPEG4Extractor() {
388 Track *track = mFirstTrack;
389 while (track) {
390 Track *next = track->next;
391
392 delete track;
393 track = next;
394 }
395 mFirstTrack = mLastTrack = NULL;
396
397 SINF *sinf = mFirstSINF;
398 while (sinf) {
399 SINF *next = sinf->next;
400 delete[] sinf->IPMPData;
401 delete sinf;
402 sinf = next;
403 }
404 mFirstSINF = NULL;
405
406 for (size_t i = 0; i < mPssh.size(); i++) {
407 delete [] mPssh[i].data;
408 }
409 }
410
flags() const411 uint32_t MPEG4Extractor::flags() const {
412 return CAN_PAUSE |
413 ((mMoofOffset == 0 || mSidxEntries.size() != 0) ?
414 (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
415 }
416
getMetaData()417 sp<MetaData> MPEG4Extractor::getMetaData() {
418 status_t err;
419 if ((err = readMetaData()) != OK) {
420 return new MetaData;
421 }
422
423 return mFileMetaData;
424 }
425
countTracks()426 size_t MPEG4Extractor::countTracks() {
427 status_t err;
428 if ((err = readMetaData()) != OK) {
429 ALOGV("MPEG4Extractor::countTracks: no tracks");
430 return 0;
431 }
432
433 size_t n = 0;
434 Track *track = mFirstTrack;
435 while (track) {
436 ++n;
437 track = track->next;
438 }
439
440 ALOGV("MPEG4Extractor::countTracks: %zu tracks", n);
441 return n;
442 }
443
getTrackMetaData(size_t index,uint32_t flags)444 sp<MetaData> MPEG4Extractor::getTrackMetaData(
445 size_t index, uint32_t flags) {
446 status_t err;
447 if ((err = readMetaData()) != OK) {
448 return NULL;
449 }
450
451 Track *track = mFirstTrack;
452 while (index > 0) {
453 if (track == NULL) {
454 return NULL;
455 }
456
457 track = track->next;
458 --index;
459 }
460
461 if (track == NULL) {
462 return NULL;
463 }
464
465 if ((flags & kIncludeExtensiveMetaData)
466 && !track->includes_expensive_metadata) {
467 track->includes_expensive_metadata = true;
468
469 const char *mime;
470 CHECK(track->meta->findCString(kKeyMIMEType, &mime));
471 if (!strncasecmp("video/", mime, 6)) {
472 // MPEG2 tracks do not provide CSD, so read the stream header
473 if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
474 off64_t offset;
475 size_t size;
476 if (track->sampleTable->getMetaDataForSample(
477 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
478 if (size > kMaxTrackHeaderSize) {
479 size = kMaxTrackHeaderSize;
480 }
481 uint8_t header[kMaxTrackHeaderSize];
482 if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
483 track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
484 }
485 }
486 }
487
488 if (mMoofOffset > 0) {
489 int64_t duration;
490 if (track->meta->findInt64(kKeyDuration, &duration)) {
491 // nothing fancy, just pick a frame near 1/4th of the duration
492 track->meta->setInt64(
493 kKeyThumbnailTime, duration / 4);
494 }
495 } else {
496 uint32_t sampleIndex;
497 uint32_t sampleTime;
498 if (track->timescale != 0 &&
499 track->sampleTable->findThumbnailSample(&sampleIndex) == OK
500 && track->sampleTable->getMetaDataForSample(
501 sampleIndex, NULL /* offset */, NULL /* size */,
502 &sampleTime) == OK) {
503 track->meta->setInt64(
504 kKeyThumbnailTime,
505 ((int64_t)sampleTime * 1000000) / track->timescale);
506 }
507 }
508 }
509 }
510
511 return track->meta;
512 }
513
MakeFourCCString(uint32_t x,char * s)514 static void MakeFourCCString(uint32_t x, char *s) {
515 s[0] = x >> 24;
516 s[1] = (x >> 16) & 0xff;
517 s[2] = (x >> 8) & 0xff;
518 s[3] = x & 0xff;
519 s[4] = '\0';
520 }
521
readMetaData()522 status_t MPEG4Extractor::readMetaData() {
523 if (mInitCheck != NO_INIT) {
524 return mInitCheck;
525 }
526
527 off64_t offset = 0;
528 status_t err;
529 bool sawMoovOrSidx = false;
530
531 while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) {
532 off64_t orig_offset = offset;
533 err = parseChunk(&offset, 0);
534
535 if (err != OK && err != UNKNOWN_ERROR) {
536 break;
537 } else if (offset <= orig_offset) {
538 // only continue parsing if the offset was advanced,
539 // otherwise we might end up in an infinite loop
540 ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset);
541 err = ERROR_MALFORMED;
542 break;
543 } else if (err == UNKNOWN_ERROR) {
544 sawMoovOrSidx = true;
545 }
546 }
547
548 if (mInitCheck == OK) {
549 if (findTrackByMimePrefix("video/") != NULL) {
550 mFileMetaData->setCString(
551 kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
552 } else if (findTrackByMimePrefix("audio/") != NULL) {
553 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
554 } else {
555 mFileMetaData->setCString(kKeyMIMEType, "application/octet-stream");
556 }
557 } else {
558 mInitCheck = err;
559 }
560
561 CHECK_NE(err, (status_t)NO_INIT);
562
563 // copy pssh data into file metadata
564 uint64_t psshsize = 0;
565 for (size_t i = 0; i < mPssh.size(); i++) {
566 psshsize += 20 + mPssh[i].datalen;
567 }
568 if (psshsize > 0 && psshsize <= UINT32_MAX) {
569 char *buf = (char*)malloc(psshsize);
570 if (!buf) {
571 ALOGE("b/28471206");
572 return NO_MEMORY;
573 }
574 char *ptr = buf;
575 for (size_t i = 0; i < mPssh.size(); i++) {
576 memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
577 memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
578 ptr += (20 + mPssh[i].datalen);
579 }
580 mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize);
581 free(buf);
582 }
583 return mInitCheck;
584 }
585
getDrmTrackInfo(size_t trackID,int * len)586 char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
587 if (mFirstSINF == NULL) {
588 return NULL;
589 }
590
591 SINF *sinf = mFirstSINF;
592 while (sinf && (trackID != sinf->trackID)) {
593 sinf = sinf->next;
594 }
595
596 if (sinf == NULL) {
597 return NULL;
598 }
599
600 *len = sinf->len;
601 return sinf->IPMPData;
602 }
603
604 // Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
readSize(off64_t offset,const sp<DataSource> & DataSource,uint8_t * numOfBytes)605 static int32_t readSize(off64_t offset,
606 const sp<DataSource> &DataSource, uint8_t *numOfBytes) {
607 uint32_t size = 0;
608 uint8_t data;
609 bool moreData = true;
610 *numOfBytes = 0;
611
612 while (moreData) {
613 if (DataSource->readAt(offset, &data, 1) < 1) {
614 return -1;
615 }
616 offset ++;
617 moreData = (data >= 128) ? true : false;
618 size = (size << 7) | (data & 0x7f); // Take last 7 bits
619 (*numOfBytes) ++;
620 }
621
622 return size;
623 }
624
parseDrmSINF(off64_t *,off64_t data_offset)625 status_t MPEG4Extractor::parseDrmSINF(
626 off64_t * /* offset */, off64_t data_offset) {
627 uint8_t updateIdTag;
628 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
629 return ERROR_IO;
630 }
631 data_offset ++;
632
633 if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
634 return ERROR_MALFORMED;
635 }
636
637 uint8_t numOfBytes;
638 int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
639 if (size < 0) {
640 return ERROR_IO;
641 }
642 data_offset += numOfBytes;
643
644 while(size >= 11 ) {
645 uint8_t descriptorTag;
646 if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
647 return ERROR_IO;
648 }
649 data_offset ++;
650
651 if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
652 return ERROR_MALFORMED;
653 }
654
655 uint8_t buffer[8];
656 //ObjectDescriptorID and ObjectDescriptor url flag
657 if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
658 return ERROR_IO;
659 }
660 data_offset += 2;
661
662 if ((buffer[1] >> 5) & 0x0001) { //url flag is set
663 return ERROR_MALFORMED;
664 }
665
666 if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
667 return ERROR_IO;
668 }
669 data_offset += 8;
670
671 if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
672 || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
673 return ERROR_MALFORMED;
674 }
675
676 SINF *sinf = new SINF;
677 sinf->trackID = U16_AT(&buffer[3]);
678 sinf->IPMPDescriptorID = buffer[7];
679 sinf->next = mFirstSINF;
680 mFirstSINF = sinf;
681
682 size -= (8 + 2 + 1);
683 }
684
685 if (size != 0) {
686 return ERROR_MALFORMED;
687 }
688
689 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
690 return ERROR_IO;
691 }
692 data_offset ++;
693
694 if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
695 return ERROR_MALFORMED;
696 }
697
698 size = readSize(data_offset, mDataSource, &numOfBytes);
699 if (size < 0) {
700 return ERROR_IO;
701 }
702 data_offset += numOfBytes;
703
704 while (size > 0) {
705 uint8_t tag;
706 int32_t dataLen;
707 if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
708 return ERROR_IO;
709 }
710 data_offset ++;
711
712 if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
713 uint8_t id;
714 dataLen = readSize(data_offset, mDataSource, &numOfBytes);
715 if (dataLen < 0) {
716 return ERROR_IO;
717 } else if (dataLen < 4) {
718 return ERROR_MALFORMED;
719 }
720 data_offset += numOfBytes;
721
722 if (mDataSource->readAt(data_offset, &id, 1) < 1) {
723 return ERROR_IO;
724 }
725 data_offset ++;
726
727 SINF *sinf = mFirstSINF;
728 while (sinf && (sinf->IPMPDescriptorID != id)) {
729 sinf = sinf->next;
730 }
731 if (sinf == NULL) {
732 return ERROR_MALFORMED;
733 }
734 sinf->len = dataLen - 3;
735 sinf->IPMPData = new (std::nothrow) char[sinf->len];
736 if (sinf->IPMPData == NULL) {
737 return ERROR_MALFORMED;
738 }
739 data_offset += 2;
740
741 if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) {
742 return ERROR_IO;
743 }
744 data_offset += sinf->len;
745
746 size -= (dataLen + numOfBytes + 1);
747 }
748 }
749
750 if (size != 0) {
751 return ERROR_MALFORMED;
752 }
753
754 return UNKNOWN_ERROR; // Return a dummy error.
755 }
756
757 struct PathAdder {
PathAdderandroid::PathAdder758 PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
759 : mPath(path) {
760 mPath->push(chunkType);
761 }
762
~PathAdderandroid::PathAdder763 ~PathAdder() {
764 mPath->pop();
765 }
766
767 private:
768 Vector<uint32_t> *mPath;
769
770 PathAdder(const PathAdder &);
771 PathAdder &operator=(const PathAdder &);
772 };
773
underMetaDataPath(const Vector<uint32_t> & path)774 static bool underMetaDataPath(const Vector<uint32_t> &path) {
775 return path.size() >= 5
776 && path[0] == FOURCC('m', 'o', 'o', 'v')
777 && path[1] == FOURCC('u', 'd', 't', 'a')
778 && path[2] == FOURCC('m', 'e', 't', 'a')
779 && path[3] == FOURCC('i', 'l', 's', 't');
780 }
781
underQTMetaPath(const Vector<uint32_t> & path,int32_t depth)782 static bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) {
783 return path.size() >= 2
784 && path[0] == FOURCC('m', 'o', 'o', 'v')
785 && path[1] == FOURCC('m', 'e', 't', 'a')
786 && (depth == 2
787 || (depth == 3
788 && (path[2] == FOURCC('h', 'd', 'l', 'r')
789 || path[2] == FOURCC('i', 'l', 's', 't')
790 || path[2] == FOURCC('k', 'e', 'y', 's'))));
791 }
792
793 // Given a time in seconds since Jan 1 1904, produce a human-readable string.
convertTimeToDate(int64_t time_1904,String8 * s)794 static bool convertTimeToDate(int64_t time_1904, String8 *s) {
795 // delta between mpeg4 time and unix epoch time
796 static const int64_t delta = (((66 * 365 + 17) * 24) * 3600);
797 if (time_1904 < INT64_MIN + delta) {
798 return false;
799 }
800 time_t time_1970 = time_1904 - delta;
801
802 char tmp[32];
803 struct tm* tm = gmtime(&time_1970);
804 if (tm != NULL &&
805 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
806 s->setTo(tmp);
807 return true;
808 }
809 return false;
810 }
811
parseChunk(off64_t * offset,int depth)812 status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
813 ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth);
814
815 if (*offset < 0) {
816 ALOGE("b/23540914");
817 return ERROR_MALFORMED;
818 }
819 if (depth > 100) {
820 ALOGE("b/27456299");
821 return ERROR_MALFORMED;
822 }
823 uint32_t hdr[2];
824 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
825 return ERROR_IO;
826 }
827 uint64_t chunk_size = ntohl(hdr[0]);
828 int32_t chunk_type = ntohl(hdr[1]);
829 off64_t data_offset = *offset + 8;
830
831 if (chunk_size == 1) {
832 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
833 return ERROR_IO;
834 }
835 chunk_size = ntoh64(chunk_size);
836 data_offset += 8;
837
838 if (chunk_size < 16) {
839 // The smallest valid chunk is 16 bytes long in this case.
840 return ERROR_MALFORMED;
841 }
842 } else if (chunk_size == 0) {
843 if (depth == 0) {
844 // atom extends to end of file
845 off64_t sourceSize;
846 if (mDataSource->getSize(&sourceSize) == OK) {
847 chunk_size = (sourceSize - *offset);
848 } else {
849 // XXX could we just pick a "sufficiently large" value here?
850 ALOGE("atom size is 0, and data source has no size");
851 return ERROR_MALFORMED;
852 }
853 } else {
854 // not allowed for non-toplevel atoms, skip it
855 *offset += 4;
856 return OK;
857 }
858 } else if (chunk_size < 8) {
859 // The smallest valid chunk is 8 bytes long.
860 ALOGE("invalid chunk size: %" PRIu64, chunk_size);
861 return ERROR_MALFORMED;
862 }
863
864 char chunk[5];
865 MakeFourCCString(chunk_type, chunk);
866 ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth);
867
868 if (kUseHexDump) {
869 static const char kWhitespace[] = " ";
870 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
871 printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size);
872
873 char buffer[256];
874 size_t n = chunk_size;
875 if (n > sizeof(buffer)) {
876 n = sizeof(buffer);
877 }
878 if (mDataSource->readAt(*offset, buffer, n)
879 < (ssize_t)n) {
880 return ERROR_IO;
881 }
882
883 hexdump(buffer, n);
884 }
885
886 PathAdder autoAdder(&mPath, chunk_type);
887
888 // (data_offset - *offset) is either 8 or 16
889 off64_t chunk_data_size = chunk_size - (data_offset - *offset);
890 if (chunk_data_size < 0) {
891 ALOGE("b/23540914");
892 return ERROR_MALFORMED;
893 }
894 if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) {
895 char errMsg[100];
896 sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
897 ALOGE("%s (b/28615448)", errMsg);
898 android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg));
899 return ERROR_MALFORMED;
900 }
901
902 if (chunk_type != FOURCC('c', 'p', 'r', 't')
903 && chunk_type != FOURCC('c', 'o', 'v', 'r')
904 && mPath.size() == 5 && underMetaDataPath(mPath)) {
905 off64_t stop_offset = *offset + chunk_size;
906 *offset = data_offset;
907 while (*offset < stop_offset) {
908 status_t err = parseChunk(offset, depth + 1);
909 if (err != OK) {
910 return err;
911 }
912 }
913
914 if (*offset != stop_offset) {
915 return ERROR_MALFORMED;
916 }
917
918 return OK;
919 }
920
921 switch(chunk_type) {
922 case FOURCC('m', 'o', 'o', 'v'):
923 case FOURCC('t', 'r', 'a', 'k'):
924 case FOURCC('m', 'd', 'i', 'a'):
925 case FOURCC('m', 'i', 'n', 'f'):
926 case FOURCC('d', 'i', 'n', 'f'):
927 case FOURCC('s', 't', 'b', 'l'):
928 case FOURCC('m', 'v', 'e', 'x'):
929 case FOURCC('m', 'o', 'o', 'f'):
930 case FOURCC('t', 'r', 'a', 'f'):
931 case FOURCC('m', 'f', 'r', 'a'):
932 case FOURCC('u', 'd', 't', 'a'):
933 case FOURCC('i', 'l', 's', 't'):
934 case FOURCC('s', 'i', 'n', 'f'):
935 case FOURCC('s', 'c', 'h', 'i'):
936 case FOURCC('e', 'd', 't', 's'):
937 case FOURCC('w', 'a', 'v', 'e'):
938 {
939 if (chunk_type == FOURCC('m', 'o', 'o', 'v') && depth != 0) {
940 ALOGE("moov: depth %d", depth);
941 return ERROR_MALFORMED;
942 }
943
944 if (chunk_type == FOURCC('m', 'o', 'o', 'v') && mInitCheck == OK) {
945 ALOGE("duplicate moov");
946 return ERROR_MALFORMED;
947 }
948
949 if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) {
950 // store the offset of the first segment
951 mMoofFound = true;
952 mMoofOffset = *offset;
953 }
954
955 if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
956 ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
957
958 if (mDataSource->flags()
959 & (DataSource::kWantsPrefetching
960 | DataSource::kIsCachingDataSource)) {
961 sp<MPEG4DataSource> cachedSource =
962 new MPEG4DataSource(mDataSource);
963
964 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
965 mDataSource = cachedSource;
966 }
967 }
968
969 if (mLastTrack == NULL)
970 return ERROR_MALFORMED;
971
972 mLastTrack->sampleTable = new SampleTable(mDataSource);
973 }
974
975 bool isTrack = false;
976 if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
977 if (depth != 1) {
978 ALOGE("trak: depth %d", depth);
979 return ERROR_MALFORMED;
980 }
981 isTrack = true;
982
983 Track *track = new Track;
984 track->next = NULL;
985 if (mLastTrack) {
986 mLastTrack->next = track;
987 } else {
988 mFirstTrack = track;
989 }
990 mLastTrack = track;
991
992 track->meta = new MetaData;
993 track->includes_expensive_metadata = false;
994 track->skipTrack = false;
995 track->timescale = 0;
996 track->meta->setCString(kKeyMIMEType, "application/octet-stream");
997 }
998
999 off64_t stop_offset = *offset + chunk_size;
1000 *offset = data_offset;
1001 while (*offset < stop_offset) {
1002 status_t err = parseChunk(offset, depth + 1);
1003 if (err != OK) {
1004 if (isTrack) {
1005 mLastTrack->skipTrack = true;
1006 break;
1007 }
1008 return err;
1009 }
1010 }
1011
1012 if (*offset != stop_offset) {
1013 return ERROR_MALFORMED;
1014 }
1015
1016 if (isTrack) {
1017 int32_t trackId;
1018 // There must be exact one track header per track.
1019 if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
1020 mLastTrack->skipTrack = true;
1021 }
1022
1023 status_t err = verifyTrack(mLastTrack);
1024 if (err != OK) {
1025 mLastTrack->skipTrack = true;
1026 }
1027
1028 if (mLastTrack->skipTrack) {
1029 Track *cur = mFirstTrack;
1030
1031 if (cur == mLastTrack) {
1032 delete cur;
1033 mFirstTrack = mLastTrack = NULL;
1034 } else {
1035 while (cur && cur->next != mLastTrack) {
1036 cur = cur->next;
1037 }
1038 if (cur) {
1039 cur->next = NULL;
1040 }
1041 delete mLastTrack;
1042 mLastTrack = cur;
1043 }
1044
1045 return OK;
1046 }
1047 } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
1048 mInitCheck = OK;
1049
1050 if (!mIsDrm) {
1051 return UNKNOWN_ERROR; // Return a dummy error.
1052 } else {
1053 return OK;
1054 }
1055 }
1056 break;
1057 }
1058
1059 case FOURCC('e', 'l', 's', 't'):
1060 {
1061 *offset += chunk_size;
1062
1063 // See 14496-12 8.6.6
1064 uint8_t version;
1065 if (mDataSource->readAt(data_offset, &version, 1) < 1) {
1066 return ERROR_IO;
1067 }
1068
1069 uint32_t entry_count;
1070 if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) {
1071 return ERROR_IO;
1072 }
1073
1074 if (entry_count != 1) {
1075 // we only support a single entry at the moment, for gapless playback
1076 ALOGW("ignoring edit list with %d entries", entry_count);
1077 } else if (mHeaderTimescale == 0) {
1078 ALOGW("ignoring edit list because timescale is 0");
1079 } else {
1080 off64_t entriesoffset = data_offset + 8;
1081 uint64_t segment_duration;
1082 int64_t media_time;
1083
1084 if (version == 1) {
1085 if (!mDataSource->getUInt64(entriesoffset, &segment_duration) ||
1086 !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) {
1087 return ERROR_IO;
1088 }
1089 } else if (version == 0) {
1090 uint32_t sd;
1091 int32_t mt;
1092 if (!mDataSource->getUInt32(entriesoffset, &sd) ||
1093 !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) {
1094 return ERROR_IO;
1095 }
1096 segment_duration = sd;
1097 media_time = mt;
1098 } else {
1099 return ERROR_IO;
1100 }
1101
1102 uint64_t halfscale = mHeaderTimescale / 2;
1103 segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale;
1104 media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale;
1105
1106 int64_t duration;
1107 int32_t samplerate;
1108 if (!mLastTrack) {
1109 return ERROR_MALFORMED;
1110 }
1111 if (mLastTrack->meta->findInt64(kKeyDuration, &duration) &&
1112 mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) {
1113
1114 int64_t delay = (media_time * samplerate + 500000) / 1000000;
1115 mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
1116
1117 int64_t paddingus = duration - (int64_t)(segment_duration + media_time);
1118 if (paddingus < 0) {
1119 // track duration from media header (which is what kKeyDuration is) might
1120 // be slightly shorter than the segment duration, which would make the
1121 // padding negative. Clamp to zero.
1122 paddingus = 0;
1123 }
1124 int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000;
1125 mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples);
1126 }
1127 }
1128 break;
1129 }
1130
1131 case FOURCC('f', 'r', 'm', 'a'):
1132 {
1133 *offset += chunk_size;
1134
1135 uint32_t original_fourcc;
1136 if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) {
1137 return ERROR_IO;
1138 }
1139 original_fourcc = ntohl(original_fourcc);
1140 ALOGV("read original format: %d", original_fourcc);
1141
1142 if (mLastTrack == NULL)
1143 return ERROR_MALFORMED;
1144
1145 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
1146 uint32_t num_channels = 0;
1147 uint32_t sample_rate = 0;
1148 if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
1149 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
1150 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
1151 }
1152 break;
1153 }
1154
1155 case FOURCC('t', 'e', 'n', 'c'):
1156 {
1157 *offset += chunk_size;
1158
1159 if (chunk_size < 32) {
1160 return ERROR_MALFORMED;
1161 }
1162
1163 // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte
1164 // default IV size, 16 bytes default KeyID
1165 // (ISO 23001-7)
1166 char buf[4];
1167 memset(buf, 0, 4);
1168 if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) {
1169 return ERROR_IO;
1170 }
1171 uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf));
1172 if (defaultAlgorithmId > 1) {
1173 // only 0 (clear) and 1 (AES-128) are valid
1174 return ERROR_MALFORMED;
1175 }
1176
1177 memset(buf, 0, 4);
1178 if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) {
1179 return ERROR_IO;
1180 }
1181 uint32_t defaultIVSize = ntohl(*((int32_t*)buf));
1182
1183 if ((defaultAlgorithmId == 0 && defaultIVSize != 0) ||
1184 (defaultAlgorithmId != 0 && defaultIVSize == 0)) {
1185 // only unencrypted data must have 0 IV size
1186 return ERROR_MALFORMED;
1187 } else if (defaultIVSize != 0 &&
1188 defaultIVSize != 8 &&
1189 defaultIVSize != 16) {
1190 // only supported sizes are 0, 8 and 16
1191 return ERROR_MALFORMED;
1192 }
1193
1194 uint8_t defaultKeyId[16];
1195
1196 if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) {
1197 return ERROR_IO;
1198 }
1199
1200 if (mLastTrack == NULL)
1201 return ERROR_MALFORMED;
1202
1203 mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId);
1204 mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize);
1205 mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16);
1206 break;
1207 }
1208
1209 case FOURCC('t', 'k', 'h', 'd'):
1210 {
1211 *offset += chunk_size;
1212
1213 status_t err;
1214 if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
1215 return err;
1216 }
1217
1218 break;
1219 }
1220
1221 case FOURCC('p', 's', 's', 'h'):
1222 {
1223 *offset += chunk_size;
1224
1225 PsshInfo pssh;
1226
1227 if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) {
1228 return ERROR_IO;
1229 }
1230
1231 uint32_t psshdatalen = 0;
1232 if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) {
1233 return ERROR_IO;
1234 }
1235 pssh.datalen = ntohl(psshdatalen);
1236 ALOGV("pssh data size: %d", pssh.datalen);
1237 if (chunk_size < 20 || pssh.datalen > chunk_size - 20) {
1238 // pssh data length exceeds size of containing box
1239 return ERROR_MALFORMED;
1240 }
1241
1242 pssh.data = new (std::nothrow) uint8_t[pssh.datalen];
1243 if (pssh.data == NULL) {
1244 return ERROR_MALFORMED;
1245 }
1246 ALOGV("allocated pssh @ %p", pssh.data);
1247 ssize_t requested = (ssize_t) pssh.datalen;
1248 if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
1249 delete[] pssh.data;
1250 return ERROR_IO;
1251 }
1252 mPssh.push_back(pssh);
1253
1254 break;
1255 }
1256
1257 case FOURCC('m', 'd', 'h', 'd'):
1258 {
1259 *offset += chunk_size;
1260
1261 if (chunk_data_size < 4 || mLastTrack == NULL) {
1262 return ERROR_MALFORMED;
1263 }
1264
1265 uint8_t version;
1266 if (mDataSource->readAt(
1267 data_offset, &version, sizeof(version))
1268 < (ssize_t)sizeof(version)) {
1269 return ERROR_IO;
1270 }
1271
1272 off64_t timescale_offset;
1273
1274 if (version == 1) {
1275 timescale_offset = data_offset + 4 + 16;
1276 } else if (version == 0) {
1277 timescale_offset = data_offset + 4 + 8;
1278 } else {
1279 return ERROR_IO;
1280 }
1281
1282 uint32_t timescale;
1283 if (mDataSource->readAt(
1284 timescale_offset, ×cale, sizeof(timescale))
1285 < (ssize_t)sizeof(timescale)) {
1286 return ERROR_IO;
1287 }
1288
1289 if (!timescale) {
1290 ALOGE("timescale should not be ZERO.");
1291 return ERROR_MALFORMED;
1292 }
1293
1294 mLastTrack->timescale = ntohl(timescale);
1295
1296 // 14496-12 says all ones means indeterminate, but some files seem to use
1297 // 0 instead. We treat both the same.
1298 int64_t duration = 0;
1299 if (version == 1) {
1300 if (mDataSource->readAt(
1301 timescale_offset + 4, &duration, sizeof(duration))
1302 < (ssize_t)sizeof(duration)) {
1303 return ERROR_IO;
1304 }
1305 if (duration != -1) {
1306 duration = ntoh64(duration);
1307 }
1308 } else {
1309 uint32_t duration32;
1310 if (mDataSource->readAt(
1311 timescale_offset + 4, &duration32, sizeof(duration32))
1312 < (ssize_t)sizeof(duration32)) {
1313 return ERROR_IO;
1314 }
1315 if (duration32 != 0xffffffff) {
1316 duration = ntohl(duration32);
1317 }
1318 }
1319 if (duration != 0 && mLastTrack->timescale != 0) {
1320 mLastTrack->meta->setInt64(
1321 kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
1322 }
1323
1324 uint8_t lang[2];
1325 off64_t lang_offset;
1326 if (version == 1) {
1327 lang_offset = timescale_offset + 4 + 8;
1328 } else if (version == 0) {
1329 lang_offset = timescale_offset + 4 + 4;
1330 } else {
1331 return ERROR_IO;
1332 }
1333
1334 if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
1335 < (ssize_t)sizeof(lang)) {
1336 return ERROR_IO;
1337 }
1338
1339 // To get the ISO-639-2/T three character language code
1340 // 1 bit pad followed by 3 5-bits characters. Each character
1341 // is packed as the difference between its ASCII value and 0x60.
1342 char lang_code[4];
1343 lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
1344 lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
1345 lang_code[2] = (lang[1] & 0x1f) + 0x60;
1346 lang_code[3] = '\0';
1347
1348 mLastTrack->meta->setCString(
1349 kKeyMediaLanguage, lang_code);
1350
1351 break;
1352 }
1353
1354 case FOURCC('s', 't', 's', 'd'):
1355 {
1356 uint8_t buffer[8];
1357 if (chunk_data_size < (off64_t)sizeof(buffer)) {
1358 return ERROR_MALFORMED;
1359 }
1360
1361 if (mDataSource->readAt(
1362 data_offset, buffer, 8) < 8) {
1363 return ERROR_IO;
1364 }
1365
1366 if (U32_AT(buffer) != 0) {
1367 // Should be version 0, flags 0.
1368 return ERROR_MALFORMED;
1369 }
1370
1371 uint32_t entry_count = U32_AT(&buffer[4]);
1372
1373 if (entry_count > 1) {
1374 // For 3GPP timed text, there could be multiple tx3g boxes contain
1375 // multiple text display formats. These formats will be used to
1376 // display the timed text.
1377 // For encrypted files, there may also be more than one entry.
1378 const char *mime;
1379
1380 if (mLastTrack == NULL)
1381 return ERROR_MALFORMED;
1382
1383 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1384 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
1385 strcasecmp(mime, "application/octet-stream")) {
1386 // For now we only support a single type of media per track.
1387 mLastTrack->skipTrack = true;
1388 *offset += chunk_size;
1389 break;
1390 }
1391 }
1392 off64_t stop_offset = *offset + chunk_size;
1393 *offset = data_offset + 8;
1394 for (uint32_t i = 0; i < entry_count; ++i) {
1395 status_t err = parseChunk(offset, depth + 1);
1396 if (err != OK) {
1397 return err;
1398 }
1399 }
1400
1401 if (*offset != stop_offset) {
1402 return ERROR_MALFORMED;
1403 }
1404 break;
1405 }
1406 case FOURCC('m', 'e', 't', 't'):
1407 {
1408 *offset += chunk_size;
1409
1410 if (mLastTrack == NULL)
1411 return ERROR_MALFORMED;
1412
1413 sp<ABuffer> buffer = new ABuffer(chunk_data_size);
1414 if (buffer->data() == NULL) {
1415 return NO_MEMORY;
1416 }
1417
1418 if (mDataSource->readAt(
1419 data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
1420 return ERROR_IO;
1421 }
1422
1423 String8 mimeFormat((const char *)(buffer->data()), chunk_data_size);
1424 mLastTrack->meta->setCString(kKeyMIMEType, mimeFormat.string());
1425
1426 break;
1427 }
1428
1429 case FOURCC('m', 'p', '4', 'a'):
1430 case FOURCC('e', 'n', 'c', 'a'):
1431 case FOURCC('s', 'a', 'm', 'r'):
1432 case FOURCC('s', 'a', 'w', 'b'):
1433 {
1434 if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')
1435 && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) {
1436 // Ignore mp4a embedded in QT wave atom
1437 *offset += chunk_size;
1438 break;
1439 }
1440
1441 uint8_t buffer[8 + 20];
1442 if (chunk_data_size < (ssize_t)sizeof(buffer)) {
1443 // Basic AudioSampleEntry size.
1444 return ERROR_MALFORMED;
1445 }
1446
1447 if (mDataSource->readAt(
1448 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
1449 return ERROR_IO;
1450 }
1451
1452 uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
1453 uint16_t version = U16_AT(&buffer[8]);
1454 uint32_t num_channels = U16_AT(&buffer[16]);
1455
1456 uint16_t sample_size = U16_AT(&buffer[18]);
1457 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
1458
1459 if (mLastTrack == NULL)
1460 return ERROR_MALFORMED;
1461
1462 off64_t stop_offset = *offset + chunk_size;
1463 *offset = data_offset + sizeof(buffer);
1464
1465 if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')) {
1466 if (version == 1) {
1467 if (mDataSource->readAt(*offset, buffer, 16) < 16) {
1468 return ERROR_IO;
1469 }
1470
1471 #if 0
1472 U32_AT(buffer); // samples per packet
1473 U32_AT(&buffer[4]); // bytes per packet
1474 U32_AT(&buffer[8]); // bytes per frame
1475 U32_AT(&buffer[12]); // bytes per sample
1476 #endif
1477 *offset += 16;
1478 } else if (version == 2) {
1479 uint8_t v2buffer[36];
1480 if (mDataSource->readAt(*offset, v2buffer, 36) < 36) {
1481 return ERROR_IO;
1482 }
1483
1484 #if 0
1485 U32_AT(v2buffer); // size of struct only
1486 sample_rate = (uint32_t)U64_AT(&v2buffer[4]); // audio sample rate
1487 num_channels = U32_AT(&v2buffer[12]); // num audio channels
1488 U32_AT(&v2buffer[16]); // always 0x7f000000
1489 sample_size = (uint16_t)U32_AT(&v2buffer[20]); // const bits per channel
1490 U32_AT(&v2buffer[24]); // format specifc flags
1491 U32_AT(&v2buffer[28]); // const bytes per audio packet
1492 U32_AT(&v2buffer[32]); // const LPCM frames per audio packet
1493 #endif
1494 *offset += 36;
1495 }
1496 }
1497
1498 if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
1499 // if the chunk type is enca, we'll get the type from the sinf/frma box later
1500 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1501 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
1502 }
1503 ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
1504 chunk, num_channels, sample_size, sample_rate);
1505 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
1506 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
1507
1508 while (*offset < stop_offset) {
1509 status_t err = parseChunk(offset, depth + 1);
1510 if (err != OK) {
1511 return err;
1512 }
1513 }
1514
1515 if (*offset != stop_offset) {
1516 return ERROR_MALFORMED;
1517 }
1518 break;
1519 }
1520
1521 case FOURCC('m', 'p', '4', 'v'):
1522 case FOURCC('e', 'n', 'c', 'v'):
1523 case FOURCC('s', '2', '6', '3'):
1524 case FOURCC('H', '2', '6', '3'):
1525 case FOURCC('h', '2', '6', '3'):
1526 case FOURCC('a', 'v', 'c', '1'):
1527 case FOURCC('h', 'v', 'c', '1'):
1528 case FOURCC('h', 'e', 'v', '1'):
1529 {
1530 uint8_t buffer[78];
1531 if (chunk_data_size < (ssize_t)sizeof(buffer)) {
1532 // Basic VideoSampleEntry size.
1533 return ERROR_MALFORMED;
1534 }
1535
1536 if (mDataSource->readAt(
1537 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
1538 return ERROR_IO;
1539 }
1540
1541 uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
1542 uint16_t width = U16_AT(&buffer[6 + 18]);
1543 uint16_t height = U16_AT(&buffer[6 + 20]);
1544
1545 // The video sample is not standard-compliant if it has invalid dimension.
1546 // Use some default width and height value, and
1547 // let the decoder figure out the actual width and height (and thus
1548 // be prepared for INFO_FOMRAT_CHANGED event).
1549 if (width == 0) width = 352;
1550 if (height == 0) height = 288;
1551
1552 // printf("*** coding='%s' width=%d height=%d\n",
1553 // chunk, width, height);
1554
1555 if (mLastTrack == NULL)
1556 return ERROR_MALFORMED;
1557
1558 if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
1559 // if the chunk type is encv, we'll get the type from the sinf/frma box later
1560 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1561 }
1562 mLastTrack->meta->setInt32(kKeyWidth, width);
1563 mLastTrack->meta->setInt32(kKeyHeight, height);
1564
1565 off64_t stop_offset = *offset + chunk_size;
1566 *offset = data_offset + sizeof(buffer);
1567 while (*offset < stop_offset) {
1568 status_t err = parseChunk(offset, depth + 1);
1569 if (err != OK) {
1570 return err;
1571 }
1572 }
1573
1574 if (*offset != stop_offset) {
1575 return ERROR_MALFORMED;
1576 }
1577 break;
1578 }
1579
1580 case FOURCC('s', 't', 'c', 'o'):
1581 case FOURCC('c', 'o', '6', '4'):
1582 {
1583 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1584 return ERROR_MALFORMED;
1585
1586 status_t err =
1587 mLastTrack->sampleTable->setChunkOffsetParams(
1588 chunk_type, data_offset, chunk_data_size);
1589
1590 *offset += chunk_size;
1591
1592 if (err != OK) {
1593 return err;
1594 }
1595
1596 break;
1597 }
1598
1599 case FOURCC('s', 't', 's', 'c'):
1600 {
1601 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1602 return ERROR_MALFORMED;
1603
1604 status_t err =
1605 mLastTrack->sampleTable->setSampleToChunkParams(
1606 data_offset, chunk_data_size);
1607
1608 *offset += chunk_size;
1609
1610 if (err != OK) {
1611 return err;
1612 }
1613
1614 break;
1615 }
1616
1617 case FOURCC('s', 't', 's', 'z'):
1618 case FOURCC('s', 't', 'z', '2'):
1619 {
1620 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1621 return ERROR_MALFORMED;
1622
1623 status_t err =
1624 mLastTrack->sampleTable->setSampleSizeParams(
1625 chunk_type, data_offset, chunk_data_size);
1626
1627 *offset += chunk_size;
1628
1629 if (err != OK) {
1630 return err;
1631 }
1632
1633 size_t max_size;
1634 err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
1635
1636 if (err != OK) {
1637 return err;
1638 }
1639
1640 if (max_size != 0) {
1641 // Assume that a given buffer only contains at most 10 chunks,
1642 // each chunk originally prefixed with a 2 byte length will
1643 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
1644 // and thus will grow by 2 bytes per chunk.
1645 if (max_size > SIZE_MAX - 10 * 2) {
1646 ALOGE("max sample size too big: %zu", max_size);
1647 return ERROR_MALFORMED;
1648 }
1649 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
1650 } else {
1651 // No size was specified. Pick a conservatively large size.
1652 uint32_t width, height;
1653 if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) ||
1654 !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) {
1655 ALOGE("No width or height, assuming worst case 1080p");
1656 width = 1920;
1657 height = 1080;
1658 } else {
1659 // A resolution was specified, check that it's not too big. The values below
1660 // were chosen so that the calculations below don't cause overflows, they're
1661 // not indicating that resolutions up to 32kx32k are actually supported.
1662 if (width > 32768 || height > 32768) {
1663 ALOGE("can't support %u x %u video", width, height);
1664 return ERROR_MALFORMED;
1665 }
1666 }
1667
1668 const char *mime;
1669 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1670 if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
1671 || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
1672 // AVC & HEVC requires compression ratio of at least 2, and uses
1673 // macroblocks
1674 max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192;
1675 } else {
1676 // For all other formats there is no minimum compression
1677 // ratio. Use compression ratio of 1.
1678 max_size = width * height * 3 / 2;
1679 }
1680 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
1681 }
1682
1683 // NOTE: setting another piece of metadata invalidates any pointers (such as the
1684 // mimetype) previously obtained, so don't cache them.
1685 const char *mime;
1686 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1687 // Calculate average frame rate.
1688 if (!strncasecmp("video/", mime, 6)) {
1689 size_t nSamples = mLastTrack->sampleTable->countSamples();
1690 if (nSamples == 0) {
1691 int32_t trackId;
1692 if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
1693 for (size_t i = 0; i < mTrex.size(); i++) {
1694 Trex *t = &mTrex.editItemAt(i);
1695 if (t->track_ID == (uint32_t) trackId) {
1696 if (t->default_sample_duration > 0) {
1697 int32_t frameRate =
1698 mLastTrack->timescale / t->default_sample_duration;
1699 mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1700 }
1701 break;
1702 }
1703 }
1704 }
1705 } else {
1706 int64_t durationUs;
1707 if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
1708 if (durationUs > 0) {
1709 int32_t frameRate = (nSamples * 1000000LL +
1710 (durationUs >> 1)) / durationUs;
1711 mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1712 }
1713 }
1714 }
1715 }
1716
1717 break;
1718 }
1719
1720 case FOURCC('s', 't', 't', 's'):
1721 {
1722 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1723 return ERROR_MALFORMED;
1724
1725 *offset += chunk_size;
1726
1727 status_t err =
1728 mLastTrack->sampleTable->setTimeToSampleParams(
1729 data_offset, chunk_data_size);
1730
1731 if (err != OK) {
1732 return err;
1733 }
1734
1735 break;
1736 }
1737
1738 case FOURCC('c', 't', 't', 's'):
1739 {
1740 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1741 return ERROR_MALFORMED;
1742
1743 *offset += chunk_size;
1744
1745 status_t err =
1746 mLastTrack->sampleTable->setCompositionTimeToSampleParams(
1747 data_offset, chunk_data_size);
1748
1749 if (err != OK) {
1750 return err;
1751 }
1752
1753 break;
1754 }
1755
1756 case FOURCC('s', 't', 's', 's'):
1757 {
1758 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1759 return ERROR_MALFORMED;
1760
1761 *offset += chunk_size;
1762
1763 status_t err =
1764 mLastTrack->sampleTable->setSyncSampleParams(
1765 data_offset, chunk_data_size);
1766
1767 if (err != OK) {
1768 return err;
1769 }
1770
1771 break;
1772 }
1773
1774 // \xA9xyz
1775 case FOURCC(0xA9, 'x', 'y', 'z'):
1776 {
1777 *offset += chunk_size;
1778
1779 // Best case the total data length inside "\xA9xyz" box
1780 // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/",
1781 // where "\x00\x04" is the text string length with value = 4,
1782 // "\0x15\xc7" is the language code = en, and "0+0" is a
1783 // location (string) value with longitude = 0 and latitude = 0.
1784 if (chunk_data_size < 8) {
1785 return ERROR_MALFORMED;
1786 }
1787
1788 // Worst case the location string length would be 18,
1789 // for instance +90.0000-180.0000, without the trailing "/" and
1790 // the string length + language code, and some devices include
1791 // an additional 8 bytes of altitude, e.g. +007.186
1792 char buffer[18 + 8];
1793
1794 // Substracting 5 from the data size is because the text string length +
1795 // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
1796 off64_t location_length = chunk_data_size - 5;
1797 if (location_length >= (off64_t) sizeof(buffer)) {
1798 return ERROR_MALFORMED;
1799 }
1800
1801 if (mDataSource->readAt(
1802 data_offset + 4, buffer, location_length) < location_length) {
1803 return ERROR_IO;
1804 }
1805
1806 buffer[location_length] = '\0';
1807 mFileMetaData->setCString(kKeyLocation, buffer);
1808 break;
1809 }
1810
1811 case FOURCC('e', 's', 'd', 's'):
1812 {
1813 *offset += chunk_size;
1814
1815 if (chunk_data_size < 4) {
1816 return ERROR_MALFORMED;
1817 }
1818
1819 uint8_t buffer[256];
1820 if (chunk_data_size > (off64_t)sizeof(buffer)) {
1821 return ERROR_BUFFER_TOO_SMALL;
1822 }
1823
1824 if (mDataSource->readAt(
1825 data_offset, buffer, chunk_data_size) < chunk_data_size) {
1826 return ERROR_IO;
1827 }
1828
1829 if (U32_AT(buffer) != 0) {
1830 // Should be version 0, flags 0.
1831 return ERROR_MALFORMED;
1832 }
1833
1834 if (mLastTrack == NULL)
1835 return ERROR_MALFORMED;
1836
1837 mLastTrack->meta->setData(
1838 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
1839
1840 if (mPath.size() >= 2
1841 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1842 // Information from the ESDS must be relied on for proper
1843 // setup of sample rate and channel count for MPEG4 Audio.
1844 // The generic header appears to only contain generic
1845 // information...
1846
1847 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1848 &buffer[4], chunk_data_size - 4);
1849
1850 if (err != OK) {
1851 return err;
1852 }
1853 }
1854 if (mPath.size() >= 2
1855 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) {
1856 // Check if the video is MPEG2
1857 ESDS esds(&buffer[4], chunk_data_size - 4);
1858
1859 uint8_t objectTypeIndication;
1860 if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) {
1861 if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) {
1862 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
1863 }
1864 }
1865 }
1866 break;
1867 }
1868
1869 case FOURCC('b', 't', 'r', 't'):
1870 {
1871 *offset += chunk_size;
1872 if (mLastTrack == NULL) {
1873 return ERROR_MALFORMED;
1874 }
1875
1876 uint8_t buffer[12];
1877 if (chunk_data_size != sizeof(buffer)) {
1878 return ERROR_MALFORMED;
1879 }
1880
1881 if (mDataSource->readAt(
1882 data_offset, buffer, chunk_data_size) < chunk_data_size) {
1883 return ERROR_IO;
1884 }
1885
1886 uint32_t maxBitrate = U32_AT(&buffer[4]);
1887 uint32_t avgBitrate = U32_AT(&buffer[8]);
1888 if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
1889 mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
1890 }
1891 if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
1892 mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
1893 }
1894 break;
1895 }
1896
1897 case FOURCC('a', 'v', 'c', 'C'):
1898 {
1899 *offset += chunk_size;
1900
1901 sp<ABuffer> buffer = new ABuffer(chunk_data_size);
1902
1903 if (buffer->data() == NULL) {
1904 ALOGE("b/28471206");
1905 return NO_MEMORY;
1906 }
1907
1908 if (mDataSource->readAt(
1909 data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
1910 return ERROR_IO;
1911 }
1912
1913 if (mLastTrack == NULL)
1914 return ERROR_MALFORMED;
1915
1916 mLastTrack->meta->setData(
1917 kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size);
1918
1919 break;
1920 }
1921 case FOURCC('h', 'v', 'c', 'C'):
1922 {
1923 sp<ABuffer> buffer = new ABuffer(chunk_data_size);
1924
1925 if (buffer->data() == NULL) {
1926 ALOGE("b/28471206");
1927 return NO_MEMORY;
1928 }
1929
1930 if (mDataSource->readAt(
1931 data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
1932 return ERROR_IO;
1933 }
1934
1935 if (mLastTrack == NULL)
1936 return ERROR_MALFORMED;
1937
1938 mLastTrack->meta->setData(
1939 kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size);
1940
1941 *offset += chunk_size;
1942 break;
1943 }
1944
1945 case FOURCC('d', '2', '6', '3'):
1946 {
1947 *offset += chunk_size;
1948 /*
1949 * d263 contains a fixed 7 bytes part:
1950 * vendor - 4 bytes
1951 * version - 1 byte
1952 * level - 1 byte
1953 * profile - 1 byte
1954 * optionally, "d263" box itself may contain a 16-byte
1955 * bit rate box (bitr)
1956 * average bit rate - 4 bytes
1957 * max bit rate - 4 bytes
1958 */
1959 char buffer[23];
1960 if (chunk_data_size != 7 &&
1961 chunk_data_size != 23) {
1962 ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size);
1963 return ERROR_MALFORMED;
1964 }
1965
1966 if (mDataSource->readAt(
1967 data_offset, buffer, chunk_data_size) < chunk_data_size) {
1968 return ERROR_IO;
1969 }
1970
1971 if (mLastTrack == NULL)
1972 return ERROR_MALFORMED;
1973
1974 mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
1975
1976 break;
1977 }
1978
1979 case FOURCC('m', 'e', 't', 'a'):
1980 {
1981 off64_t stop_offset = *offset + chunk_size;
1982 *offset = data_offset;
1983 bool isParsingMetaKeys = underQTMetaPath(mPath, 2);
1984 if (!isParsingMetaKeys) {
1985 uint8_t buffer[4];
1986 if (chunk_data_size < (off64_t)sizeof(buffer)) {
1987 *offset = stop_offset;
1988 return ERROR_MALFORMED;
1989 }
1990
1991 if (mDataSource->readAt(
1992 data_offset, buffer, 4) < 4) {
1993 *offset = stop_offset;
1994 return ERROR_IO;
1995 }
1996
1997 if (U32_AT(buffer) != 0) {
1998 // Should be version 0, flags 0.
1999
2000 // If it's not, let's assume this is one of those
2001 // apparently malformed chunks that don't have flags
2002 // and completely different semantics than what's
2003 // in the MPEG4 specs and skip it.
2004 *offset = stop_offset;
2005 return OK;
2006 }
2007 *offset += sizeof(buffer);
2008 }
2009
2010 while (*offset < stop_offset) {
2011 status_t err = parseChunk(offset, depth + 1);
2012 if (err != OK) {
2013 return err;
2014 }
2015 }
2016
2017 if (*offset != stop_offset) {
2018 return ERROR_MALFORMED;
2019 }
2020 break;
2021 }
2022
2023 case FOURCC('m', 'e', 'a', 'n'):
2024 case FOURCC('n', 'a', 'm', 'e'):
2025 case FOURCC('d', 'a', 't', 'a'):
2026 {
2027 *offset += chunk_size;
2028
2029 if (mPath.size() == 6 && underMetaDataPath(mPath)) {
2030 status_t err = parseITunesMetaData(data_offset, chunk_data_size);
2031
2032 if (err != OK) {
2033 return err;
2034 }
2035 }
2036
2037 break;
2038 }
2039
2040 case FOURCC('m', 'v', 'h', 'd'):
2041 {
2042 *offset += chunk_size;
2043
2044 if (depth != 1) {
2045 ALOGE("mvhd: depth %d", depth);
2046 return ERROR_MALFORMED;
2047 }
2048 if (chunk_data_size < 32) {
2049 return ERROR_MALFORMED;
2050 }
2051
2052 uint8_t header[32];
2053 if (mDataSource->readAt(
2054 data_offset, header, sizeof(header))
2055 < (ssize_t)sizeof(header)) {
2056 return ERROR_IO;
2057 }
2058
2059 uint64_t creationTime;
2060 uint64_t duration = 0;
2061 if (header[0] == 1) {
2062 creationTime = U64_AT(&header[4]);
2063 mHeaderTimescale = U32_AT(&header[20]);
2064 duration = U64_AT(&header[24]);
2065 if (duration == 0xffffffffffffffff) {
2066 duration = 0;
2067 }
2068 } else if (header[0] != 0) {
2069 return ERROR_MALFORMED;
2070 } else {
2071 creationTime = U32_AT(&header[4]);
2072 mHeaderTimescale = U32_AT(&header[12]);
2073 uint32_t d32 = U32_AT(&header[16]);
2074 if (d32 == 0xffffffff) {
2075 d32 = 0;
2076 }
2077 duration = d32;
2078 }
2079 if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
2080 mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
2081 }
2082
2083 String8 s;
2084 if (convertTimeToDate(creationTime, &s)) {
2085 mFileMetaData->setCString(kKeyDate, s.string());
2086 }
2087
2088
2089 break;
2090 }
2091
2092 case FOURCC('m', 'e', 'h', 'd'):
2093 {
2094 *offset += chunk_size;
2095
2096 if (chunk_data_size < 8) {
2097 return ERROR_MALFORMED;
2098 }
2099
2100 uint8_t flags[4];
2101 if (mDataSource->readAt(
2102 data_offset, flags, sizeof(flags))
2103 < (ssize_t)sizeof(flags)) {
2104 return ERROR_IO;
2105 }
2106
2107 uint64_t duration = 0;
2108 if (flags[0] == 1) {
2109 // 64 bit
2110 if (chunk_data_size < 12) {
2111 return ERROR_MALFORMED;
2112 }
2113 mDataSource->getUInt64(data_offset + 4, &duration);
2114 if (duration == 0xffffffffffffffff) {
2115 duration = 0;
2116 }
2117 } else if (flags[0] == 0) {
2118 // 32 bit
2119 uint32_t d32;
2120 mDataSource->getUInt32(data_offset + 4, &d32);
2121 if (d32 == 0xffffffff) {
2122 d32 = 0;
2123 }
2124 duration = d32;
2125 } else {
2126 return ERROR_MALFORMED;
2127 }
2128
2129 if (duration != 0 && mHeaderTimescale != 0) {
2130 mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
2131 }
2132
2133 break;
2134 }
2135
2136 case FOURCC('m', 'd', 'a', 't'):
2137 {
2138 ALOGV("mdat chunk, drm: %d", mIsDrm);
2139
2140 mMdatFound = true;
2141
2142 if (!mIsDrm) {
2143 *offset += chunk_size;
2144 break;
2145 }
2146
2147 if (chunk_size < 8) {
2148 return ERROR_MALFORMED;
2149 }
2150
2151 return parseDrmSINF(offset, data_offset);
2152 }
2153
2154 case FOURCC('h', 'd', 'l', 'r'):
2155 {
2156 *offset += chunk_size;
2157
2158 if (underQTMetaPath(mPath, 3)) {
2159 break;
2160 }
2161
2162 uint32_t buffer;
2163 if (mDataSource->readAt(
2164 data_offset + 8, &buffer, 4) < 4) {
2165 return ERROR_IO;
2166 }
2167
2168 uint32_t type = ntohl(buffer);
2169 // For the 3GPP file format, the handler-type within the 'hdlr' box
2170 // shall be 'text'. We also want to support 'sbtl' handler type
2171 // for a practical reason as various MPEG4 containers use it.
2172 if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
2173 if (mLastTrack != NULL) {
2174 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
2175 }
2176 }
2177
2178 break;
2179 }
2180
2181 case FOURCC('k', 'e', 'y', 's'):
2182 {
2183 *offset += chunk_size;
2184
2185 if (underQTMetaPath(mPath, 3)) {
2186 status_t err = parseQTMetaKey(data_offset, chunk_data_size);
2187 if (err != OK) {
2188 return err;
2189 }
2190 }
2191 break;
2192 }
2193
2194 case FOURCC('t', 'r', 'e', 'x'):
2195 {
2196 *offset += chunk_size;
2197
2198 if (chunk_data_size < 24) {
2199 return ERROR_IO;
2200 }
2201 Trex trex;
2202 if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) ||
2203 !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) ||
2204 !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) ||
2205 !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) ||
2206 !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) {
2207 return ERROR_IO;
2208 }
2209 mTrex.add(trex);
2210 break;
2211 }
2212
2213 case FOURCC('t', 'x', '3', 'g'):
2214 {
2215 if (mLastTrack == NULL)
2216 return ERROR_MALFORMED;
2217
2218 uint32_t type;
2219 const void *data;
2220 size_t size = 0;
2221 if (!mLastTrack->meta->findData(
2222 kKeyTextFormatData, &type, &data, &size)) {
2223 size = 0;
2224 }
2225
2226 if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
2227 return ERROR_MALFORMED;
2228 }
2229
2230 uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
2231 if (buffer == NULL) {
2232 return ERROR_MALFORMED;
2233 }
2234
2235 if (size > 0) {
2236 memcpy(buffer, data, size);
2237 }
2238
2239 if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
2240 < chunk_size) {
2241 delete[] buffer;
2242 buffer = NULL;
2243
2244 // advance read pointer so we don't end up reading this again
2245 *offset += chunk_size;
2246 return ERROR_IO;
2247 }
2248
2249 mLastTrack->meta->setData(
2250 kKeyTextFormatData, 0, buffer, size + chunk_size);
2251
2252 delete[] buffer;
2253
2254 *offset += chunk_size;
2255 break;
2256 }
2257
2258 case FOURCC('c', 'o', 'v', 'r'):
2259 {
2260 *offset += chunk_size;
2261
2262 if (mFileMetaData != NULL) {
2263 ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64,
2264 chunk_data_size, data_offset);
2265
2266 if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) {
2267 return ERROR_MALFORMED;
2268 }
2269 sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
2270 if (buffer->data() == NULL) {
2271 ALOGE("b/28471206");
2272 return NO_MEMORY;
2273 }
2274 if (mDataSource->readAt(
2275 data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
2276 return ERROR_IO;
2277 }
2278 const int kSkipBytesOfDataBox = 16;
2279 if (chunk_data_size <= kSkipBytesOfDataBox) {
2280 return ERROR_MALFORMED;
2281 }
2282
2283 mFileMetaData->setData(
2284 kKeyAlbumArt, MetaData::TYPE_NONE,
2285 buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
2286 }
2287
2288 break;
2289 }
2290
2291 case FOURCC('c', 'o', 'l', 'r'):
2292 {
2293 *offset += chunk_size;
2294 // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
2295 // ignore otherwise
2296 if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
2297 status_t err = parseColorInfo(data_offset, chunk_data_size);
2298 if (err != OK) {
2299 return err;
2300 }
2301 }
2302
2303 break;
2304 }
2305
2306 case FOURCC('t', 'i', 't', 'l'):
2307 case FOURCC('p', 'e', 'r', 'f'):
2308 case FOURCC('a', 'u', 't', 'h'):
2309 case FOURCC('g', 'n', 'r', 'e'):
2310 case FOURCC('a', 'l', 'b', 'm'):
2311 case FOURCC('y', 'r', 'r', 'c'):
2312 {
2313 *offset += chunk_size;
2314
2315 status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
2316
2317 if (err != OK) {
2318 return err;
2319 }
2320
2321 break;
2322 }
2323
2324 case FOURCC('I', 'D', '3', '2'):
2325 {
2326 *offset += chunk_size;
2327
2328 if (chunk_data_size < 6) {
2329 return ERROR_MALFORMED;
2330 }
2331
2332 parseID3v2MetaData(data_offset + 6);
2333
2334 break;
2335 }
2336
2337 case FOURCC('-', '-', '-', '-'):
2338 {
2339 mLastCommentMean.clear();
2340 mLastCommentName.clear();
2341 mLastCommentData.clear();
2342 *offset += chunk_size;
2343 break;
2344 }
2345
2346 case FOURCC('s', 'i', 'd', 'x'):
2347 {
2348 status_t err = parseSegmentIndex(data_offset, chunk_data_size);
2349 if (err != OK) {
2350 return err;
2351 }
2352 *offset += chunk_size;
2353 return UNKNOWN_ERROR; // stop parsing after sidx
2354 }
2355
2356 case FOURCC('a', 'c', '-', '3'):
2357 {
2358 *offset += chunk_size;
2359 return parseAC3SampleEntry(data_offset);
2360 }
2361
2362 case FOURCC('f', 't', 'y', 'p'):
2363 {
2364 if (chunk_data_size < 8 || depth != 0) {
2365 return ERROR_MALFORMED;
2366 }
2367
2368 off64_t stop_offset = *offset + chunk_size;
2369 uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4;
2370 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
2371 if (i == 1) {
2372 // Skip this index, it refers to the minorVersion,
2373 // not a brand.
2374 continue;
2375 }
2376
2377 uint32_t brand;
2378 if (mDataSource->readAt(data_offset + 4 * i, &brand, 4) < 4) {
2379 return ERROR_MALFORMED;
2380 }
2381
2382 brand = ntohl(brand);
2383 if (brand == FOURCC('q', 't', ' ', ' ')) {
2384 mIsQT = true;
2385 break;
2386 }
2387 }
2388
2389 *offset = stop_offset;
2390
2391 break;
2392 }
2393
2394 default:
2395 {
2396 // check if we're parsing 'ilst' for meta keys
2397 // if so, treat type as a number (key-id).
2398 if (underQTMetaPath(mPath, 3)) {
2399 status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
2400 if (err != OK) {
2401 return err;
2402 }
2403 }
2404
2405 *offset += chunk_size;
2406 break;
2407 }
2408 }
2409
2410 return OK;
2411 }
2412
parseAC3SampleEntry(off64_t offset)2413 status_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) {
2414 // skip 16 bytes:
2415 // + 6-byte reserved,
2416 // + 2-byte data reference index,
2417 // + 8-byte reserved
2418 offset += 16;
2419 uint16_t channelCount;
2420 if (!mDataSource->getUInt16(offset, &channelCount)) {
2421 return ERROR_MALFORMED;
2422 }
2423 // skip 8 bytes:
2424 // + 2-byte channelCount,
2425 // + 2-byte sample size,
2426 // + 4-byte reserved
2427 offset += 8;
2428 uint16_t sampleRate;
2429 if (!mDataSource->getUInt16(offset, &sampleRate)) {
2430 ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate");
2431 return ERROR_MALFORMED;
2432 }
2433
2434 // skip 4 bytes:
2435 // + 2-byte sampleRate,
2436 // + 2-byte reserved
2437 offset += 4;
2438 return parseAC3SpecificBox(offset, sampleRate);
2439 }
2440
parseAC3SpecificBox(off64_t offset,uint16_t sampleRate)2441 status_t MPEG4Extractor::parseAC3SpecificBox(
2442 off64_t offset, uint16_t sampleRate) {
2443 uint32_t size;
2444 // + 4-byte size
2445 // + 4-byte type
2446 // + 3-byte payload
2447 const uint32_t kAC3SpecificBoxSize = 11;
2448 if (!mDataSource->getUInt32(offset, &size) || size < kAC3SpecificBoxSize) {
2449 ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read specific box size");
2450 return ERROR_MALFORMED;
2451 }
2452
2453 offset += 4;
2454 uint32_t type;
2455 if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'a', 'c', '3')) {
2456 ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3");
2457 return ERROR_MALFORMED;
2458 }
2459
2460 offset += 4;
2461 const uint32_t kAC3SpecificBoxPayloadSize = 3;
2462 uint8_t chunk[kAC3SpecificBoxPayloadSize];
2463 if (mDataSource->readAt(offset, chunk, sizeof(chunk)) != sizeof(chunk)) {
2464 ALOGE("MPEG4Extractor: error while reading ac-3 specific block: bitstream fields");
2465 return ERROR_MALFORMED;
2466 }
2467
2468 ABitReader br(chunk, sizeof(chunk));
2469 static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
2470 static const unsigned sampleRateTable[] = {48000, 44100, 32000};
2471
2472 unsigned fscod = br.getBits(2);
2473 if (fscod == 3) {
2474 ALOGE("Incorrect fscod (3) in AC3 header");
2475 return ERROR_MALFORMED;
2476 }
2477 unsigned boxSampleRate = sampleRateTable[fscod];
2478 if (boxSampleRate != sampleRate) {
2479 ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
2480 boxSampleRate, sampleRate);
2481 return ERROR_MALFORMED;
2482 }
2483
2484 unsigned bsid = br.getBits(5);
2485 if (bsid > 8) {
2486 ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
2487 return ERROR_MALFORMED;
2488 }
2489
2490 // skip
2491 unsigned bsmod __unused = br.getBits(3);
2492
2493 unsigned acmod = br.getBits(3);
2494 unsigned lfeon = br.getBits(1);
2495 unsigned channelCount = channelCountTable[acmod] + lfeon;
2496
2497 if (mLastTrack == NULL) {
2498 return ERROR_MALFORMED;
2499 }
2500 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
2501 mLastTrack->meta->setInt32(kKeyChannelCount, channelCount);
2502 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
2503 return OK;
2504 }
2505
parseSegmentIndex(off64_t offset,size_t size)2506 status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
2507 ALOGV("MPEG4Extractor::parseSegmentIndex");
2508
2509 if (size < 12) {
2510 return -EINVAL;
2511 }
2512
2513 uint32_t flags;
2514 if (!mDataSource->getUInt32(offset, &flags)) {
2515 return ERROR_MALFORMED;
2516 }
2517
2518 uint32_t version = flags >> 24;
2519 flags &= 0xffffff;
2520
2521 ALOGV("sidx version %d", version);
2522
2523 uint32_t referenceId;
2524 if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
2525 return ERROR_MALFORMED;
2526 }
2527
2528 uint32_t timeScale;
2529 if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
2530 return ERROR_MALFORMED;
2531 }
2532 ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
2533 if (timeScale == 0)
2534 return ERROR_MALFORMED;
2535
2536 uint64_t earliestPresentationTime;
2537 uint64_t firstOffset;
2538
2539 offset += 12;
2540 size -= 12;
2541
2542 if (version == 0) {
2543 if (size < 8) {
2544 return -EINVAL;
2545 }
2546 uint32_t tmp;
2547 if (!mDataSource->getUInt32(offset, &tmp)) {
2548 return ERROR_MALFORMED;
2549 }
2550 earliestPresentationTime = tmp;
2551 if (!mDataSource->getUInt32(offset + 4, &tmp)) {
2552 return ERROR_MALFORMED;
2553 }
2554 firstOffset = tmp;
2555 offset += 8;
2556 size -= 8;
2557 } else {
2558 if (size < 16) {
2559 return -EINVAL;
2560 }
2561 if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
2562 return ERROR_MALFORMED;
2563 }
2564 if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
2565 return ERROR_MALFORMED;
2566 }
2567 offset += 16;
2568 size -= 16;
2569 }
2570 ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset);
2571
2572 if (size < 4) {
2573 return -EINVAL;
2574 }
2575
2576 uint16_t referenceCount;
2577 if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
2578 return ERROR_MALFORMED;
2579 }
2580 offset += 4;
2581 size -= 4;
2582 ALOGV("refcount: %d", referenceCount);
2583
2584 if (size < referenceCount * 12) {
2585 return -EINVAL;
2586 }
2587
2588 uint64_t total_duration = 0;
2589 for (unsigned int i = 0; i < referenceCount; i++) {
2590 uint32_t d1, d2, d3;
2591
2592 if (!mDataSource->getUInt32(offset, &d1) || // size
2593 !mDataSource->getUInt32(offset + 4, &d2) || // duration
2594 !mDataSource->getUInt32(offset + 8, &d3)) { // flags
2595 return ERROR_MALFORMED;
2596 }
2597
2598 if (d1 & 0x80000000) {
2599 ALOGW("sub-sidx boxes not supported yet");
2600 }
2601 bool sap = d3 & 0x80000000;
2602 uint32_t saptype = (d3 >> 28) & 7;
2603 if (!sap || (saptype != 1 && saptype != 2)) {
2604 // type 1 and 2 are sync samples
2605 ALOGW("not a stream access point, or unsupported type: %08x", d3);
2606 }
2607 total_duration += d2;
2608 offset += 12;
2609 ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
2610 SidxEntry se;
2611 se.mSize = d1 & 0x7fffffff;
2612 se.mDurationUs = 1000000LL * d2 / timeScale;
2613 mSidxEntries.add(se);
2614 }
2615
2616 uint64_t sidxDuration = total_duration * 1000000 / timeScale;
2617
2618 if (mLastTrack == NULL)
2619 return ERROR_MALFORMED;
2620
2621 int64_t metaDuration;
2622 if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
2623 mLastTrack->meta->setInt64(kKeyDuration, sidxDuration);
2624 }
2625 return OK;
2626 }
2627
parseQTMetaKey(off64_t offset,size_t size)2628 status_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) {
2629 if (size < 8) {
2630 return ERROR_MALFORMED;
2631 }
2632
2633 uint32_t count;
2634 if (!mDataSource->getUInt32(offset + 4, &count)) {
2635 return ERROR_MALFORMED;
2636 }
2637
2638 if (mMetaKeyMap.size() > 0) {
2639 ALOGW("'keys' atom seen again, discarding existing entries");
2640 mMetaKeyMap.clear();
2641 }
2642
2643 off64_t keyOffset = offset + 8;
2644 off64_t stopOffset = offset + size;
2645 for (size_t i = 1; i <= count; i++) {
2646 if (keyOffset + 8 > stopOffset) {
2647 return ERROR_MALFORMED;
2648 }
2649
2650 uint32_t keySize;
2651 if (!mDataSource->getUInt32(keyOffset, &keySize)
2652 || keySize < 8
2653 || keyOffset + keySize > stopOffset) {
2654 return ERROR_MALFORMED;
2655 }
2656
2657 uint32_t type;
2658 if (!mDataSource->getUInt32(keyOffset + 4, &type)
2659 || type != FOURCC('m', 'd', 't', 'a')) {
2660 return ERROR_MALFORMED;
2661 }
2662
2663 keySize -= 8;
2664 keyOffset += 8;
2665
2666 sp<ABuffer> keyData = new ABuffer(keySize);
2667 if (keyData->data() == NULL) {
2668 return ERROR_MALFORMED;
2669 }
2670 if (mDataSource->readAt(
2671 keyOffset, keyData->data(), keySize) < (ssize_t) keySize) {
2672 return ERROR_MALFORMED;
2673 }
2674
2675 AString key((const char *)keyData->data(), keySize);
2676 mMetaKeyMap.add(i, key);
2677
2678 keyOffset += keySize;
2679 }
2680 return OK;
2681 }
2682
parseQTMetaVal(int32_t keyId,off64_t offset,size_t size)2683 status_t MPEG4Extractor::parseQTMetaVal(
2684 int32_t keyId, off64_t offset, size_t size) {
2685 ssize_t index = mMetaKeyMap.indexOfKey(keyId);
2686 if (index < 0) {
2687 // corresponding key is not present, ignore
2688 return ERROR_MALFORMED;
2689 }
2690
2691 if (size <= 16) {
2692 return ERROR_MALFORMED;
2693 }
2694 uint32_t dataSize;
2695 if (!mDataSource->getUInt32(offset, &dataSize)
2696 || dataSize > size || dataSize <= 16) {
2697 return ERROR_MALFORMED;
2698 }
2699 uint32_t atomFourCC;
2700 if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
2701 || atomFourCC != FOURCC('d', 'a', 't', 'a')) {
2702 return ERROR_MALFORMED;
2703 }
2704 uint32_t dataType;
2705 if (!mDataSource->getUInt32(offset + 8, &dataType)
2706 || ((dataType & 0xff000000) != 0)) {
2707 // not well-known type
2708 return ERROR_MALFORMED;
2709 }
2710
2711 dataSize -= 16;
2712 offset += 16;
2713
2714 if (dataType == 23 && dataSize >= 4) {
2715 // BE Float32
2716 uint32_t val;
2717 if (!mDataSource->getUInt32(offset, &val)) {
2718 return ERROR_MALFORMED;
2719 }
2720 if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
2721 mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val);
2722 }
2723 } else if (dataType == 67 && dataSize >= 4) {
2724 // BE signed int32
2725 uint32_t val;
2726 if (!mDataSource->getUInt32(offset, &val)) {
2727 return ERROR_MALFORMED;
2728 }
2729 if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
2730 mFileMetaData->setInt32(kKeyTemporalLayerCount, val);
2731 }
2732 } else {
2733 // add more keys if needed
2734 ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
2735 }
2736
2737 return OK;
2738 }
2739
parseTrackHeader(off64_t data_offset,off64_t data_size)2740 status_t MPEG4Extractor::parseTrackHeader(
2741 off64_t data_offset, off64_t data_size) {
2742 if (data_size < 4) {
2743 return ERROR_MALFORMED;
2744 }
2745
2746 uint8_t version;
2747 if (mDataSource->readAt(data_offset, &version, 1) < 1) {
2748 return ERROR_IO;
2749 }
2750
2751 size_t dynSize = (version == 1) ? 36 : 24;
2752
2753 uint8_t buffer[36 + 60];
2754
2755 if (data_size != (off64_t)dynSize + 60) {
2756 return ERROR_MALFORMED;
2757 }
2758
2759 if (mDataSource->readAt(
2760 data_offset, buffer, data_size) < (ssize_t)data_size) {
2761 return ERROR_IO;
2762 }
2763
2764 uint64_t ctime __unused, mtime __unused, duration __unused;
2765 int32_t id;
2766
2767 if (version == 1) {
2768 ctime = U64_AT(&buffer[4]);
2769 mtime = U64_AT(&buffer[12]);
2770 id = U32_AT(&buffer[20]);
2771 duration = U64_AT(&buffer[28]);
2772 } else if (version == 0) {
2773 ctime = U32_AT(&buffer[4]);
2774 mtime = U32_AT(&buffer[8]);
2775 id = U32_AT(&buffer[12]);
2776 duration = U32_AT(&buffer[20]);
2777 } else {
2778 return ERROR_UNSUPPORTED;
2779 }
2780
2781 if (mLastTrack == NULL)
2782 return ERROR_MALFORMED;
2783
2784 mLastTrack->meta->setInt32(kKeyTrackID, id);
2785
2786 size_t matrixOffset = dynSize + 16;
2787 int32_t a00 = U32_AT(&buffer[matrixOffset]);
2788 int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
2789 int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
2790 int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
2791
2792 #if 0
2793 int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
2794 int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
2795
2796 ALOGI("x' = %.2f * x + %.2f * y + %.2f",
2797 a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
2798 ALOGI("y' = %.2f * x + %.2f * y + %.2f",
2799 a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
2800 #endif
2801
2802 uint32_t rotationDegrees;
2803
2804 static const int32_t kFixedOne = 0x10000;
2805 if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
2806 // Identity, no rotation
2807 rotationDegrees = 0;
2808 } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
2809 rotationDegrees = 90;
2810 } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
2811 rotationDegrees = 270;
2812 } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
2813 rotationDegrees = 180;
2814 } else {
2815 ALOGW("We only support 0,90,180,270 degree rotation matrices");
2816 rotationDegrees = 0;
2817 }
2818
2819 if (rotationDegrees != 0) {
2820 mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
2821 }
2822
2823 // Handle presentation display size, which could be different
2824 // from the image size indicated by kKeyWidth and kKeyHeight.
2825 uint32_t width = U32_AT(&buffer[dynSize + 52]);
2826 uint32_t height = U32_AT(&buffer[dynSize + 56]);
2827 mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
2828 mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
2829
2830 return OK;
2831 }
2832
parseITunesMetaData(off64_t offset,size_t size)2833 status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
2834 if (size == 0) {
2835 return OK;
2836 }
2837
2838 if (size < 4 || size == SIZE_MAX) {
2839 return ERROR_MALFORMED;
2840 }
2841
2842 uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
2843 if (buffer == NULL) {
2844 return ERROR_MALFORMED;
2845 }
2846 if (mDataSource->readAt(
2847 offset, buffer, size) != (ssize_t)size) {
2848 delete[] buffer;
2849 buffer = NULL;
2850
2851 return ERROR_IO;
2852 }
2853
2854 uint32_t flags = U32_AT(buffer);
2855
2856 uint32_t metadataKey = 0;
2857 char chunk[5];
2858 MakeFourCCString(mPath[4], chunk);
2859 ALOGV("meta: %s @ %lld", chunk, (long long)offset);
2860 switch ((int32_t)mPath[4]) {
2861 case FOURCC(0xa9, 'a', 'l', 'b'):
2862 {
2863 metadataKey = kKeyAlbum;
2864 break;
2865 }
2866 case FOURCC(0xa9, 'A', 'R', 'T'):
2867 {
2868 metadataKey = kKeyArtist;
2869 break;
2870 }
2871 case FOURCC('a', 'A', 'R', 'T'):
2872 {
2873 metadataKey = kKeyAlbumArtist;
2874 break;
2875 }
2876 case FOURCC(0xa9, 'd', 'a', 'y'):
2877 {
2878 metadataKey = kKeyYear;
2879 break;
2880 }
2881 case FOURCC(0xa9, 'n', 'a', 'm'):
2882 {
2883 metadataKey = kKeyTitle;
2884 break;
2885 }
2886 case FOURCC(0xa9, 'w', 'r', 't'):
2887 {
2888 metadataKey = kKeyWriter;
2889 break;
2890 }
2891 case FOURCC('c', 'o', 'v', 'r'):
2892 {
2893 metadataKey = kKeyAlbumArt;
2894 break;
2895 }
2896 case FOURCC('g', 'n', 'r', 'e'):
2897 {
2898 metadataKey = kKeyGenre;
2899 break;
2900 }
2901 case FOURCC(0xa9, 'g', 'e', 'n'):
2902 {
2903 metadataKey = kKeyGenre;
2904 break;
2905 }
2906 case FOURCC('c', 'p', 'i', 'l'):
2907 {
2908 if (size == 9 && flags == 21) {
2909 char tmp[16];
2910 sprintf(tmp, "%d",
2911 (int)buffer[size - 1]);
2912
2913 mFileMetaData->setCString(kKeyCompilation, tmp);
2914 }
2915 break;
2916 }
2917 case FOURCC('t', 'r', 'k', 'n'):
2918 {
2919 if (size == 16 && flags == 0) {
2920 char tmp[16];
2921 uint16_t* pTrack = (uint16_t*)&buffer[10];
2922 uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
2923 sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
2924
2925 mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
2926 }
2927 break;
2928 }
2929 case FOURCC('d', 'i', 's', 'k'):
2930 {
2931 if ((size == 14 || size == 16) && flags == 0) {
2932 char tmp[16];
2933 uint16_t* pDisc = (uint16_t*)&buffer[10];
2934 uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
2935 sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
2936
2937 mFileMetaData->setCString(kKeyDiscNumber, tmp);
2938 }
2939 break;
2940 }
2941 case FOURCC('-', '-', '-', '-'):
2942 {
2943 buffer[size] = '\0';
2944 switch (mPath[5]) {
2945 case FOURCC('m', 'e', 'a', 'n'):
2946 mLastCommentMean.setTo((const char *)buffer + 4);
2947 break;
2948 case FOURCC('n', 'a', 'm', 'e'):
2949 mLastCommentName.setTo((const char *)buffer + 4);
2950 break;
2951 case FOURCC('d', 'a', 't', 'a'):
2952 if (size < 8) {
2953 delete[] buffer;
2954 buffer = NULL;
2955 ALOGE("b/24346430");
2956 return ERROR_MALFORMED;
2957 }
2958 mLastCommentData.setTo((const char *)buffer + 8);
2959 break;
2960 }
2961
2962 // Once we have a set of mean/name/data info, go ahead and process
2963 // it to see if its something we are interested in. Whether or not
2964 // were are interested in the specific tag, make sure to clear out
2965 // the set so we can be ready to process another tuple should one
2966 // show up later in the file.
2967 if ((mLastCommentMean.length() != 0) &&
2968 (mLastCommentName.length() != 0) &&
2969 (mLastCommentData.length() != 0)) {
2970
2971 if (mLastCommentMean == "com.apple.iTunes"
2972 && mLastCommentName == "iTunSMPB") {
2973 int32_t delay, padding;
2974 if (sscanf(mLastCommentData,
2975 " %*x %x %x %*x", &delay, &padding) == 2) {
2976 if (mLastTrack == NULL) {
2977 delete[] buffer;
2978 return ERROR_MALFORMED;
2979 }
2980
2981 mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
2982 mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
2983 }
2984 }
2985
2986 mLastCommentMean.clear();
2987 mLastCommentName.clear();
2988 mLastCommentData.clear();
2989 }
2990 break;
2991 }
2992
2993 default:
2994 break;
2995 }
2996
2997 if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
2998 if (metadataKey == kKeyAlbumArt) {
2999 mFileMetaData->setData(
3000 kKeyAlbumArt, MetaData::TYPE_NONE,
3001 buffer + 8, size - 8);
3002 } else if (metadataKey == kKeyGenre) {
3003 if (flags == 0) {
3004 // uint8_t genre code, iTunes genre codes are
3005 // the standard id3 codes, except they start
3006 // at 1 instead of 0 (e.g. Pop is 14, not 13)
3007 // We use standard id3 numbering, so subtract 1.
3008 int genrecode = (int)buffer[size - 1];
3009 genrecode--;
3010 if (genrecode < 0) {
3011 genrecode = 255; // reserved for 'unknown genre'
3012 }
3013 char genre[10];
3014 sprintf(genre, "%d", genrecode);
3015
3016 mFileMetaData->setCString(metadataKey, genre);
3017 } else if (flags == 1) {
3018 // custom genre string
3019 buffer[size] = '\0';
3020
3021 mFileMetaData->setCString(
3022 metadataKey, (const char *)buffer + 8);
3023 }
3024 } else {
3025 buffer[size] = '\0';
3026
3027 mFileMetaData->setCString(
3028 metadataKey, (const char *)buffer + 8);
3029 }
3030 }
3031
3032 delete[] buffer;
3033 buffer = NULL;
3034
3035 return OK;
3036 }
3037
parseColorInfo(off64_t offset,size_t size)3038 status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
3039 if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
3040 return ERROR_MALFORMED;
3041 }
3042
3043 uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
3044 if (buffer == NULL) {
3045 return ERROR_MALFORMED;
3046 }
3047 if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
3048 delete[] buffer;
3049 buffer = NULL;
3050
3051 return ERROR_IO;
3052 }
3053
3054 int32_t type = U32_AT(&buffer[0]);
3055 if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
3056 || (type == FOURCC('n', 'c', 'l', 'c') && size >= 10)) {
3057 int32_t primaries = U16_AT(&buffer[4]);
3058 int32_t transfer = U16_AT(&buffer[6]);
3059 int32_t coeffs = U16_AT(&buffer[8]);
3060 bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);
3061
3062 ColorAspects aspects;
3063 ColorUtils::convertIsoColorAspectsToCodecAspects(
3064 primaries, transfer, coeffs, fullRange, aspects);
3065
3066 // only store the first color specification
3067 if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) {
3068 mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries);
3069 mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer);
3070 mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
3071 mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange);
3072 }
3073 }
3074
3075 delete[] buffer;
3076 buffer = NULL;
3077
3078 return OK;
3079 }
3080
parse3GPPMetaData(off64_t offset,size_t size,int depth)3081 status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
3082 if (size < 4 || size == SIZE_MAX) {
3083 return ERROR_MALFORMED;
3084 }
3085
3086 uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
3087 if (buffer == NULL) {
3088 return ERROR_MALFORMED;
3089 }
3090 if (mDataSource->readAt(
3091 offset, buffer, size) != (ssize_t)size) {
3092 delete[] buffer;
3093 buffer = NULL;
3094
3095 return ERROR_IO;
3096 }
3097
3098 uint32_t metadataKey = 0;
3099 switch (mPath[depth]) {
3100 case FOURCC('t', 'i', 't', 'l'):
3101 {
3102 metadataKey = kKeyTitle;
3103 break;
3104 }
3105 case FOURCC('p', 'e', 'r', 'f'):
3106 {
3107 metadataKey = kKeyArtist;
3108 break;
3109 }
3110 case FOURCC('a', 'u', 't', 'h'):
3111 {
3112 metadataKey = kKeyWriter;
3113 break;
3114 }
3115 case FOURCC('g', 'n', 'r', 'e'):
3116 {
3117 metadataKey = kKeyGenre;
3118 break;
3119 }
3120 case FOURCC('a', 'l', 'b', 'm'):
3121 {
3122 if (buffer[size - 1] != '\0') {
3123 char tmp[4];
3124 sprintf(tmp, "%u", buffer[size - 1]);
3125
3126 mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
3127 }
3128
3129 metadataKey = kKeyAlbum;
3130 break;
3131 }
3132 case FOURCC('y', 'r', 'r', 'c'):
3133 {
3134 if (size < 6) {
3135 delete[] buffer;
3136 buffer = NULL;
3137 ALOGE("b/62133227");
3138 android_errorWriteLog(0x534e4554, "62133227");
3139 return ERROR_MALFORMED;
3140 }
3141 char tmp[5];
3142 uint16_t year = U16_AT(&buffer[4]);
3143
3144 if (year < 10000) {
3145 sprintf(tmp, "%u", year);
3146
3147 mFileMetaData->setCString(kKeyYear, tmp);
3148 }
3149 break;
3150 }
3151
3152 default:
3153 break;
3154 }
3155
3156 if (metadataKey > 0) {
3157 bool isUTF8 = true; // Common case
3158 char16_t *framedata = NULL;
3159 int len16 = 0; // Number of UTF-16 characters
3160
3161 // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
3162 if (size < 6) {
3163 delete[] buffer;
3164 buffer = NULL;
3165 return ERROR_MALFORMED;
3166 }
3167
3168 if (size - 6 >= 4) {
3169 len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
3170 framedata = (char16_t *)(buffer + 6);
3171 if (0xfffe == *framedata) {
3172 // endianness marker (BOM) doesn't match host endianness
3173 for (int i = 0; i < len16; i++) {
3174 framedata[i] = bswap_16(framedata[i]);
3175 }
3176 // BOM is now swapped to 0xfeff, we will execute next block too
3177 }
3178
3179 if (0xfeff == *framedata) {
3180 // Remove the BOM
3181 framedata++;
3182 len16--;
3183 isUTF8 = false;
3184 }
3185 // else normal non-zero-length UTF-8 string
3186 // we can't handle UTF-16 without BOM as there is no other
3187 // indication of encoding.
3188 }
3189
3190 if (isUTF8) {
3191 buffer[size] = 0;
3192 mFileMetaData->setCString(metadataKey, (const char *)buffer + 6);
3193 } else {
3194 // Convert from UTF-16 string to UTF-8 string.
3195 String8 tmpUTF8str(framedata, len16);
3196 mFileMetaData->setCString(metadataKey, tmpUTF8str.string());
3197 }
3198 }
3199
3200 delete[] buffer;
3201 buffer = NULL;
3202
3203 return OK;
3204 }
3205
parseID3v2MetaData(off64_t offset)3206 void MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
3207 ID3 id3(mDataSource, true /* ignorev1 */, offset);
3208
3209 if (id3.isValid()) {
3210 struct Map {
3211 int key;
3212 const char *tag1;
3213 const char *tag2;
3214 };
3215 static const Map kMap[] = {
3216 { kKeyAlbum, "TALB", "TAL" },
3217 { kKeyArtist, "TPE1", "TP1" },
3218 { kKeyAlbumArtist, "TPE2", "TP2" },
3219 { kKeyComposer, "TCOM", "TCM" },
3220 { kKeyGenre, "TCON", "TCO" },
3221 { kKeyTitle, "TIT2", "TT2" },
3222 { kKeyYear, "TYE", "TYER" },
3223 { kKeyAuthor, "TXT", "TEXT" },
3224 { kKeyCDTrackNumber, "TRK", "TRCK" },
3225 { kKeyDiscNumber, "TPA", "TPOS" },
3226 { kKeyCompilation, "TCP", "TCMP" },
3227 };
3228 static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
3229
3230 for (size_t i = 0; i < kNumMapEntries; ++i) {
3231 if (!mFileMetaData->hasData(kMap[i].key)) {
3232 ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
3233 if (it->done()) {
3234 delete it;
3235 it = new ID3::Iterator(id3, kMap[i].tag2);
3236 }
3237
3238 if (it->done()) {
3239 delete it;
3240 continue;
3241 }
3242
3243 String8 s;
3244 it->getString(&s);
3245 delete it;
3246
3247 mFileMetaData->setCString(kMap[i].key, s);
3248 }
3249 }
3250
3251 size_t dataSize;
3252 String8 mime;
3253 const void *data = id3.getAlbumArt(&dataSize, &mime);
3254
3255 if (data) {
3256 mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
3257 mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
3258 }
3259 }
3260 }
3261
getTrack(size_t index)3262 sp<IMediaSource> MPEG4Extractor::getTrack(size_t index) {
3263 status_t err;
3264 if ((err = readMetaData()) != OK) {
3265 return NULL;
3266 }
3267
3268 Track *track = mFirstTrack;
3269 while (index > 0) {
3270 if (track == NULL) {
3271 return NULL;
3272 }
3273
3274 track = track->next;
3275 --index;
3276 }
3277
3278 if (track == NULL) {
3279 return NULL;
3280 }
3281
3282
3283 Trex *trex = NULL;
3284 int32_t trackId;
3285 if (track->meta->findInt32(kKeyTrackID, &trackId)) {
3286 for (size_t i = 0; i < mTrex.size(); i++) {
3287 Trex *t = &mTrex.editItemAt(i);
3288 if (t->track_ID == (uint32_t) trackId) {
3289 trex = t;
3290 break;
3291 }
3292 }
3293 } else {
3294 ALOGE("b/21657957");
3295 return NULL;
3296 }
3297
3298 ALOGV("getTrack called, pssh: %zu", mPssh.size());
3299
3300 const char *mime;
3301 if (!track->meta->findCString(kKeyMIMEType, &mime)) {
3302 return NULL;
3303 }
3304
3305 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3306 uint32_t type;
3307 const void *data;
3308 size_t size;
3309 if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) {
3310 return NULL;
3311 }
3312
3313 const uint8_t *ptr = (const uint8_t *)data;
3314
3315 if (size < 7 || ptr[0] != 1) { // configurationVersion == 1
3316 return NULL;
3317 }
3318 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
3319 uint32_t type;
3320 const void *data;
3321 size_t size;
3322 if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) {
3323 return NULL;
3324 }
3325
3326 const uint8_t *ptr = (const uint8_t *)data;
3327
3328 if (size < 22 || ptr[0] != 1) { // configurationVersion == 1
3329 return NULL;
3330 }
3331 }
3332
3333 sp<MPEG4Source> source = new MPEG4Source(this,
3334 track->meta, mDataSource, track->timescale, track->sampleTable,
3335 mSidxEntries, trex, mMoofOffset);
3336 if (source->init() != OK) {
3337 return NULL;
3338 }
3339 return source;
3340 }
3341
3342 // static
verifyTrack(Track * track)3343 status_t MPEG4Extractor::verifyTrack(Track *track) {
3344 const char *mime;
3345 CHECK(track->meta->findCString(kKeyMIMEType, &mime));
3346
3347 uint32_t type;
3348 const void *data;
3349 size_t size;
3350 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3351 if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
3352 || type != kTypeAVCC) {
3353 return ERROR_MALFORMED;
3354 }
3355 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
3356 if (!track->meta->findData(kKeyHVCC, &type, &data, &size)
3357 || type != kTypeHVCC) {
3358 return ERROR_MALFORMED;
3359 }
3360 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
3361 || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
3362 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
3363 if (!track->meta->findData(kKeyESDS, &type, &data, &size)
3364 || type != kTypeESDS) {
3365 return ERROR_MALFORMED;
3366 }
3367 }
3368
3369 if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
3370 // Make sure we have all the metadata we need.
3371 ALOGE("stbl atom missing/invalid.");
3372 return ERROR_MALFORMED;
3373 }
3374
3375 if (track->timescale == 0) {
3376 ALOGE("timescale invalid.");
3377 return ERROR_MALFORMED;
3378 }
3379
3380 return OK;
3381 }
3382
3383 typedef enum {
3384 //AOT_NONE = -1,
3385 //AOT_NULL_OBJECT = 0,
3386 //AOT_AAC_MAIN = 1, /**< Main profile */
3387 AOT_AAC_LC = 2, /**< Low Complexity object */
3388 //AOT_AAC_SSR = 3,
3389 //AOT_AAC_LTP = 4,
3390 AOT_SBR = 5,
3391 //AOT_AAC_SCAL = 6,
3392 //AOT_TWIN_VQ = 7,
3393 //AOT_CELP = 8,
3394 //AOT_HVXC = 9,
3395 //AOT_RSVD_10 = 10, /**< (reserved) */
3396 //AOT_RSVD_11 = 11, /**< (reserved) */
3397 //AOT_TTSI = 12, /**< TTSI Object */
3398 //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */
3399 //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */
3400 //AOT_GEN_MIDI = 15, /**< General MIDI object */
3401 //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
3402 AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */
3403 //AOT_RSVD_18 = 18, /**< (reserved) */
3404 //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */
3405 AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */
3406 //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */
3407 AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */
3408 AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */
3409 //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */
3410 //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */
3411 //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */
3412 //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */
3413 //AOT_RSVD_28 = 28, /**< might become SSC */
3414 AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */
3415 //AOT_MPEGS = 30, /**< MPEG Surround */
3416
3417 AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */
3418
3419 //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */
3420 //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */
3421 //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */
3422 //AOT_RSVD_35 = 35, /**< might become DST */
3423 //AOT_RSVD_36 = 36, /**< might become ALS */
3424 //AOT_AAC_SLS = 37, /**< AAC + SLS */
3425 //AOT_SLS = 38, /**< SLS */
3426 //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */
3427
3428 //AOT_USAC = 42, /**< USAC */
3429 //AOT_SAOC = 43, /**< SAOC */
3430 //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
3431
3432 //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */
3433 } AUDIO_OBJECT_TYPE;
3434
updateAudioTrackInfoFromESDS_MPEG4Audio(const void * esds_data,size_t esds_size)3435 status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
3436 const void *esds_data, size_t esds_size) {
3437 ESDS esds(esds_data, esds_size);
3438
3439 uint8_t objectTypeIndication;
3440 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
3441 return ERROR_MALFORMED;
3442 }
3443
3444 if (objectTypeIndication == 0xe1) {
3445 // This isn't MPEG4 audio at all, it's QCELP 14k...
3446 if (mLastTrack == NULL)
3447 return ERROR_MALFORMED;
3448
3449 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
3450 return OK;
3451 }
3452
3453 if (objectTypeIndication == 0x6b) {
3454 // The media subtype is MP3 audio
3455 // Our software MP3 audio decoder may not be able to handle
3456 // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
3457 ALOGE("MP3 track in MP4/3GPP file is not supported");
3458 return ERROR_UNSUPPORTED;
3459 }
3460
3461 const uint8_t *csd;
3462 size_t csd_size;
3463 if (esds.getCodecSpecificInfo(
3464 (const void **)&csd, &csd_size) != OK) {
3465 return ERROR_MALFORMED;
3466 }
3467
3468 if (kUseHexDump) {
3469 printf("ESD of size %zu\n", csd_size);
3470 hexdump(csd, csd_size);
3471 }
3472
3473 if (csd_size == 0) {
3474 // There's no further information, i.e. no codec specific data
3475 // Let's assume that the information provided in the mpeg4 headers
3476 // is accurate and hope for the best.
3477
3478 return OK;
3479 }
3480
3481 if (csd_size < 2) {
3482 return ERROR_MALFORMED;
3483 }
3484
3485 static uint32_t kSamplingRate[] = {
3486 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
3487 16000, 12000, 11025, 8000, 7350
3488 };
3489
3490 ABitReader br(csd, csd_size);
3491 uint32_t objectType = br.getBits(5);
3492
3493 if (objectType == 31) { // AAC-ELD => additional 6 bits
3494 objectType = 32 + br.getBits(6);
3495 }
3496
3497 if (mLastTrack == NULL)
3498 return ERROR_MALFORMED;
3499
3500 //keep AOT type
3501 mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
3502
3503 uint32_t freqIndex = br.getBits(4);
3504
3505 int32_t sampleRate = 0;
3506 int32_t numChannels = 0;
3507 if (freqIndex == 15) {
3508 if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
3509 sampleRate = br.getBits(24);
3510 numChannels = br.getBits(4);
3511 } else {
3512 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3513 numChannels = br.getBits(4);
3514
3515 if (freqIndex == 13 || freqIndex == 14) {
3516 return ERROR_MALFORMED;
3517 }
3518
3519 sampleRate = kSamplingRate[freqIndex];
3520 }
3521
3522 if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
3523 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3524 uint32_t extFreqIndex = br.getBits(4);
3525 int32_t extSampleRate __unused;
3526 if (extFreqIndex == 15) {
3527 if (csd_size < 8) {
3528 return ERROR_MALFORMED;
3529 }
3530 if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
3531 extSampleRate = br.getBits(24);
3532 } else {
3533 if (extFreqIndex == 13 || extFreqIndex == 14) {
3534 return ERROR_MALFORMED;
3535 }
3536 extSampleRate = kSamplingRate[extFreqIndex];
3537 }
3538 //TODO: save the extension sampling rate value in meta data =>
3539 // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
3540 }
3541
3542 switch (numChannels) {
3543 // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
3544 case 0:
3545 case 1:// FC
3546 case 2:// FL FR
3547 case 3:// FC, FL FR
3548 case 4:// FC, FL FR, RC
3549 case 5:// FC, FL FR, SL SR
3550 case 6:// FC, FL FR, SL SR, LFE
3551 //numChannels already contains the right value
3552 break;
3553 case 11:// FC, FL FR, SL SR, RC, LFE
3554 numChannels = 7;
3555 break;
3556 case 7: // FC, FCL FCR, FL FR, SL SR, LFE
3557 case 12:// FC, FL FR, SL SR, RL RR, LFE
3558 case 14:// FC, FL FR, SL SR, LFE, FHL FHR
3559 numChannels = 8;
3560 break;
3561 default:
3562 return ERROR_UNSUPPORTED;
3563 }
3564
3565 {
3566 if (objectType == AOT_SBR || objectType == AOT_PS) {
3567 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3568 objectType = br.getBits(5);
3569
3570 if (objectType == AOT_ESCAPE) {
3571 if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
3572 objectType = 32 + br.getBits(6);
3573 }
3574 }
3575 if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
3576 objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
3577 objectType == AOT_ER_BSAC) {
3578 if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
3579 const int32_t frameLengthFlag __unused = br.getBits(1);
3580
3581 const int32_t dependsOnCoreCoder = br.getBits(1);
3582
3583 if (dependsOnCoreCoder ) {
3584 if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
3585 const int32_t coreCoderDelay __unused = br.getBits(14);
3586 }
3587
3588 int32_t extensionFlag = -1;
3589 if (br.numBitsLeft() > 0) {
3590 extensionFlag = br.getBits(1);
3591 } else {
3592 switch (objectType) {
3593 // 14496-3 4.5.1.1 extensionFlag
3594 case AOT_AAC_LC:
3595 extensionFlag = 0;
3596 break;
3597 case AOT_ER_AAC_LC:
3598 case AOT_ER_AAC_SCAL:
3599 case AOT_ER_BSAC:
3600 case AOT_ER_AAC_LD:
3601 extensionFlag = 1;
3602 break;
3603 default:
3604 return ERROR_MALFORMED;
3605 break;
3606 }
3607 ALOGW("csd missing extension flag; assuming %d for object type %u.",
3608 extensionFlag, objectType);
3609 }
3610
3611 if (numChannels == 0) {
3612 int32_t channelsEffectiveNum = 0;
3613 int32_t channelsNum = 0;
3614 if (br.numBitsLeft() < 32) {
3615 return ERROR_MALFORMED;
3616 }
3617 const int32_t ElementInstanceTag __unused = br.getBits(4);
3618 const int32_t Profile __unused = br.getBits(2);
3619 const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
3620 const int32_t NumFrontChannelElements = br.getBits(4);
3621 const int32_t NumSideChannelElements = br.getBits(4);
3622 const int32_t NumBackChannelElements = br.getBits(4);
3623 const int32_t NumLfeChannelElements = br.getBits(2);
3624 const int32_t NumAssocDataElements __unused = br.getBits(3);
3625 const int32_t NumValidCcElements __unused = br.getBits(4);
3626
3627 const int32_t MonoMixdownPresent = br.getBits(1);
3628
3629 if (MonoMixdownPresent != 0) {
3630 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3631 const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
3632 }
3633
3634 if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3635 const int32_t StereoMixdownPresent = br.getBits(1);
3636 if (StereoMixdownPresent != 0) {
3637 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3638 const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
3639 }
3640
3641 if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3642 const int32_t MatrixMixdownIndexPresent = br.getBits(1);
3643 if (MatrixMixdownIndexPresent != 0) {
3644 if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
3645 const int32_t MatrixMixdownIndex __unused = br.getBits(2);
3646 const int32_t PseudoSurroundEnable __unused = br.getBits(1);
3647 }
3648
3649 int i;
3650 for (i=0; i < NumFrontChannelElements; i++) {
3651 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3652 const int32_t FrontElementIsCpe = br.getBits(1);
3653 const int32_t FrontElementTagSelect __unused = br.getBits(4);
3654 channelsNum += FrontElementIsCpe ? 2 : 1;
3655 }
3656
3657 for (i=0; i < NumSideChannelElements; i++) {
3658 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3659 const int32_t SideElementIsCpe = br.getBits(1);
3660 const int32_t SideElementTagSelect __unused = br.getBits(4);
3661 channelsNum += SideElementIsCpe ? 2 : 1;
3662 }
3663
3664 for (i=0; i < NumBackChannelElements; i++) {
3665 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3666 const int32_t BackElementIsCpe = br.getBits(1);
3667 const int32_t BackElementTagSelect __unused = br.getBits(4);
3668 channelsNum += BackElementIsCpe ? 2 : 1;
3669 }
3670 channelsEffectiveNum = channelsNum;
3671
3672 for (i=0; i < NumLfeChannelElements; i++) {
3673 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3674 const int32_t LfeElementTagSelect __unused = br.getBits(4);
3675 channelsNum += 1;
3676 }
3677 ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
3678 ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
3679 numChannels = channelsNum;
3680 }
3681 }
3682 }
3683
3684 if (numChannels == 0) {
3685 return ERROR_UNSUPPORTED;
3686 }
3687
3688 if (mLastTrack == NULL)
3689 return ERROR_MALFORMED;
3690
3691 int32_t prevSampleRate;
3692 CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
3693
3694 if (prevSampleRate != sampleRate) {
3695 ALOGV("mpeg4 audio sample rate different from previous setting. "
3696 "was: %d, now: %d", prevSampleRate, sampleRate);
3697 }
3698
3699 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
3700
3701 int32_t prevChannelCount;
3702 CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
3703
3704 if (prevChannelCount != numChannels) {
3705 ALOGV("mpeg4 audio channel count different from previous setting. "
3706 "was: %d, now: %d", prevChannelCount, numChannels);
3707 }
3708
3709 mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
3710
3711 return OK;
3712 }
3713
3714 ////////////////////////////////////////////////////////////////////////////////
3715
MPEG4Source(const sp<MPEG4Extractor> & owner,const sp<MetaData> & format,const sp<DataSource> & dataSource,int32_t timeScale,const sp<SampleTable> & sampleTable,Vector<SidxEntry> & sidx,const Trex * trex,off64_t firstMoofOffset)3716 MPEG4Source::MPEG4Source(
3717 const sp<MPEG4Extractor> &owner,
3718 const sp<MetaData> &format,
3719 const sp<DataSource> &dataSource,
3720 int32_t timeScale,
3721 const sp<SampleTable> &sampleTable,
3722 Vector<SidxEntry> &sidx,
3723 const Trex *trex,
3724 off64_t firstMoofOffset)
3725 : mOwner(owner),
3726 mFormat(format),
3727 mDataSource(dataSource),
3728 mTimescale(timeScale),
3729 mSampleTable(sampleTable),
3730 mCurrentSampleIndex(0),
3731 mCurrentFragmentIndex(0),
3732 mSegments(sidx),
3733 mTrex(trex),
3734 mFirstMoofOffset(firstMoofOffset),
3735 mCurrentMoofOffset(firstMoofOffset),
3736 mNextMoofOffset(-1),
3737 mCurrentTime(0),
3738 mCurrentSampleInfoAllocSize(0),
3739 mCurrentSampleInfoSizes(NULL),
3740 mCurrentSampleInfoOffsetsAllocSize(0),
3741 mCurrentSampleInfoOffsets(NULL),
3742 mIsAVC(false),
3743 mIsHEVC(false),
3744 mNALLengthSize(0),
3745 mStarted(false),
3746 mGroup(NULL),
3747 mBuffer(NULL),
3748 mWantsNALFragments(false),
3749 mSrcBuffer(NULL) {
3750
3751 memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
3752
3753 mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
3754 mDefaultIVSize = 0;
3755 mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
3756 uint32_t keytype;
3757 const void *key;
3758 size_t keysize;
3759 if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
3760 CHECK(keysize <= 16);
3761 memset(mCryptoKey, 0, 16);
3762 memcpy(mCryptoKey, key, keysize);
3763 }
3764
3765 const char *mime;
3766 bool success = mFormat->findCString(kKeyMIMEType, &mime);
3767 CHECK(success);
3768
3769 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
3770 mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
3771
3772 if (mIsAVC) {
3773 uint32_t type;
3774 const void *data;
3775 size_t size;
3776 CHECK(format->findData(kKeyAVCC, &type, &data, &size));
3777
3778 const uint8_t *ptr = (const uint8_t *)data;
3779
3780 CHECK(size >= 7);
3781 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
3782
3783 // The number of bytes used to encode the length of a NAL unit.
3784 mNALLengthSize = 1 + (ptr[4] & 3);
3785 } else if (mIsHEVC) {
3786 uint32_t type;
3787 const void *data;
3788 size_t size;
3789 CHECK(format->findData(kKeyHVCC, &type, &data, &size));
3790
3791 const uint8_t *ptr = (const uint8_t *)data;
3792
3793 CHECK(size >= 22);
3794 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
3795
3796 mNALLengthSize = 1 + (ptr[14 + 7] & 3);
3797 }
3798
3799 CHECK(format->findInt32(kKeyTrackID, &mTrackId));
3800
3801 }
3802
init()3803 status_t MPEG4Source::init() {
3804 if (mFirstMoofOffset != 0) {
3805 off64_t offset = mFirstMoofOffset;
3806 return parseChunk(&offset);
3807 }
3808 return OK;
3809 }
3810
~MPEG4Source()3811 MPEG4Source::~MPEG4Source() {
3812 if (mStarted) {
3813 stop();
3814 }
3815 free(mCurrentSampleInfoSizes);
3816 free(mCurrentSampleInfoOffsets);
3817 }
3818
start(MetaData * params)3819 status_t MPEG4Source::start(MetaData *params) {
3820 Mutex::Autolock autoLock(mLock);
3821
3822 CHECK(!mStarted);
3823
3824 int32_t val;
3825 if (params && params->findInt32(kKeyWantsNALFragments, &val)
3826 && val != 0) {
3827 mWantsNALFragments = true;
3828 } else {
3829 mWantsNALFragments = false;
3830 }
3831
3832 int32_t tmp;
3833 CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp));
3834 size_t max_size = tmp;
3835
3836 // A somewhat arbitrary limit that should be sufficient for 8k video frames
3837 // If you see the message below for a valid input stream: increase the limit
3838 const size_t kMaxBufferSize = 64 * 1024 * 1024;
3839 if (max_size > kMaxBufferSize) {
3840 ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize);
3841 return ERROR_MALFORMED;
3842 }
3843 if (max_size == 0) {
3844 ALOGE("zero max input size");
3845 return ERROR_MALFORMED;
3846 }
3847
3848 // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize.
3849 const size_t kMaxBuffers = 8;
3850 const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers);
3851 mGroup = new MediaBufferGroup(buffers, max_size);
3852 mSrcBuffer = new (std::nothrow) uint8_t[max_size];
3853 if (mSrcBuffer == NULL) {
3854 // file probably specified a bad max size
3855 delete mGroup;
3856 mGroup = NULL;
3857 return ERROR_MALFORMED;
3858 }
3859
3860 mStarted = true;
3861
3862 return OK;
3863 }
3864
stop()3865 status_t MPEG4Source::stop() {
3866 Mutex::Autolock autoLock(mLock);
3867
3868 CHECK(mStarted);
3869
3870 if (mBuffer != NULL) {
3871 mBuffer->release();
3872 mBuffer = NULL;
3873 }
3874
3875 delete[] mSrcBuffer;
3876 mSrcBuffer = NULL;
3877
3878 delete mGroup;
3879 mGroup = NULL;
3880
3881 mStarted = false;
3882 mCurrentSampleIndex = 0;
3883
3884 return OK;
3885 }
3886
parseChunk(off64_t * offset)3887 status_t MPEG4Source::parseChunk(off64_t *offset) {
3888 uint32_t hdr[2];
3889 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
3890 return ERROR_IO;
3891 }
3892 uint64_t chunk_size = ntohl(hdr[0]);
3893 uint32_t chunk_type = ntohl(hdr[1]);
3894 off64_t data_offset = *offset + 8;
3895
3896 if (chunk_size == 1) {
3897 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
3898 return ERROR_IO;
3899 }
3900 chunk_size = ntoh64(chunk_size);
3901 data_offset += 8;
3902
3903 if (chunk_size < 16) {
3904 // The smallest valid chunk is 16 bytes long in this case.
3905 return ERROR_MALFORMED;
3906 }
3907 } else if (chunk_size < 8) {
3908 // The smallest valid chunk is 8 bytes long.
3909 return ERROR_MALFORMED;
3910 }
3911
3912 char chunk[5];
3913 MakeFourCCString(chunk_type, chunk);
3914 ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
3915
3916 off64_t chunk_data_size = *offset + chunk_size - data_offset;
3917
3918 switch(chunk_type) {
3919
3920 case FOURCC('t', 'r', 'a', 'f'):
3921 case FOURCC('m', 'o', 'o', 'f'): {
3922 off64_t stop_offset = *offset + chunk_size;
3923 *offset = data_offset;
3924 while (*offset < stop_offset) {
3925 status_t err = parseChunk(offset);
3926 if (err != OK) {
3927 return err;
3928 }
3929 }
3930 if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
3931 // *offset points to the box following this moof. Find the next moof from there.
3932
3933 while (true) {
3934 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
3935 // no more box to the end of file.
3936 break;
3937 }
3938 chunk_size = ntohl(hdr[0]);
3939 chunk_type = ntohl(hdr[1]);
3940 if (chunk_size == 1) {
3941 // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box
3942 // which is defined in 4.2 Object Structure.
3943 // When chunk_size==1, 8 bytes follows as "largesize".
3944 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
3945 return ERROR_IO;
3946 }
3947 chunk_size = ntoh64(chunk_size);
3948 if (chunk_size < 16) {
3949 // The smallest valid chunk is 16 bytes long in this case.
3950 return ERROR_MALFORMED;
3951 }
3952 } else if (chunk_size == 0) {
3953 // next box extends to end of file.
3954 } else if (chunk_size < 8) {
3955 // The smallest valid chunk is 8 bytes long in this case.
3956 return ERROR_MALFORMED;
3957 }
3958
3959 if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
3960 mNextMoofOffset = *offset;
3961 break;
3962 } else if (chunk_size == 0) {
3963 break;
3964 }
3965 *offset += chunk_size;
3966 }
3967 }
3968 break;
3969 }
3970
3971 case FOURCC('t', 'f', 'h', 'd'): {
3972 status_t err;
3973 if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
3974 return err;
3975 }
3976 *offset += chunk_size;
3977 break;
3978 }
3979
3980 case FOURCC('t', 'r', 'u', 'n'): {
3981 status_t err;
3982 if (mLastParsedTrackId == mTrackId) {
3983 if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
3984 return err;
3985 }
3986 }
3987
3988 *offset += chunk_size;
3989 break;
3990 }
3991
3992 case FOURCC('s', 'a', 'i', 'z'): {
3993 status_t err;
3994 if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
3995 return err;
3996 }
3997 *offset += chunk_size;
3998 break;
3999 }
4000 case FOURCC('s', 'a', 'i', 'o'): {
4001 status_t err;
4002 if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
4003 return err;
4004 }
4005 *offset += chunk_size;
4006 break;
4007 }
4008
4009 case FOURCC('m', 'd', 'a', 't'): {
4010 // parse DRM info if present
4011 ALOGV("MPEG4Source::parseChunk mdat");
4012 // if saiz/saoi was previously observed, do something with the sampleinfos
4013 *offset += chunk_size;
4014 break;
4015 }
4016
4017 default: {
4018 *offset += chunk_size;
4019 break;
4020 }
4021 }
4022 return OK;
4023 }
4024
parseSampleAuxiliaryInformationSizes(off64_t offset,off64_t)4025 status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
4026 off64_t offset, off64_t /* size */) {
4027 ALOGV("parseSampleAuxiliaryInformationSizes");
4028 // 14496-12 8.7.12
4029 uint8_t version;
4030 if (mDataSource->readAt(
4031 offset, &version, sizeof(version))
4032 < (ssize_t)sizeof(version)) {
4033 return ERROR_IO;
4034 }
4035
4036 if (version != 0) {
4037 return ERROR_UNSUPPORTED;
4038 }
4039 offset++;
4040
4041 uint32_t flags;
4042 if (!mDataSource->getUInt24(offset, &flags)) {
4043 return ERROR_IO;
4044 }
4045 offset += 3;
4046
4047 if (flags & 1) {
4048 uint32_t tmp;
4049 if (!mDataSource->getUInt32(offset, &tmp)) {
4050 return ERROR_MALFORMED;
4051 }
4052 mCurrentAuxInfoType = tmp;
4053 offset += 4;
4054 if (!mDataSource->getUInt32(offset, &tmp)) {
4055 return ERROR_MALFORMED;
4056 }
4057 mCurrentAuxInfoTypeParameter = tmp;
4058 offset += 4;
4059 }
4060
4061 uint8_t defsize;
4062 if (mDataSource->readAt(offset, &defsize, 1) != 1) {
4063 return ERROR_MALFORMED;
4064 }
4065 mCurrentDefaultSampleInfoSize = defsize;
4066 offset++;
4067
4068 uint32_t smplcnt;
4069 if (!mDataSource->getUInt32(offset, &smplcnt)) {
4070 return ERROR_MALFORMED;
4071 }
4072 mCurrentSampleInfoCount = smplcnt;
4073 offset += 4;
4074
4075 if (mCurrentDefaultSampleInfoSize != 0) {
4076 ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
4077 return OK;
4078 }
4079 if (smplcnt > mCurrentSampleInfoAllocSize) {
4080 uint8_t * newPtr = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
4081 if (newPtr == NULL) {
4082 ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoAllocSize, smplcnt);
4083 return NO_MEMORY;
4084 }
4085 mCurrentSampleInfoSizes = newPtr;
4086 mCurrentSampleInfoAllocSize = smplcnt;
4087 }
4088
4089 mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
4090 return OK;
4091 }
4092
parseSampleAuxiliaryInformationOffsets(off64_t offset,off64_t)4093 status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
4094 off64_t offset, off64_t /* size */) {
4095 ALOGV("parseSampleAuxiliaryInformationOffsets");
4096 // 14496-12 8.7.13
4097 uint8_t version;
4098 if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
4099 return ERROR_IO;
4100 }
4101 offset++;
4102
4103 uint32_t flags;
4104 if (!mDataSource->getUInt24(offset, &flags)) {
4105 return ERROR_IO;
4106 }
4107 offset += 3;
4108
4109 uint32_t entrycount;
4110 if (!mDataSource->getUInt32(offset, &entrycount)) {
4111 return ERROR_IO;
4112 }
4113 offset += 4;
4114 if (entrycount == 0) {
4115 return OK;
4116 }
4117 if (entrycount > UINT32_MAX / 8) {
4118 return ERROR_MALFORMED;
4119 }
4120
4121 if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
4122 uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
4123 if (newPtr == NULL) {
4124 ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
4125 return NO_MEMORY;
4126 }
4127 mCurrentSampleInfoOffsets = newPtr;
4128 mCurrentSampleInfoOffsetsAllocSize = entrycount;
4129 }
4130 mCurrentSampleInfoOffsetCount = entrycount;
4131
4132 if (mCurrentSampleInfoOffsets == NULL) {
4133 return OK;
4134 }
4135
4136 for (size_t i = 0; i < entrycount; i++) {
4137 if (version == 0) {
4138 uint32_t tmp;
4139 if (!mDataSource->getUInt32(offset, &tmp)) {
4140 return ERROR_IO;
4141 }
4142 mCurrentSampleInfoOffsets[i] = tmp;
4143 offset += 4;
4144 } else {
4145 uint64_t tmp;
4146 if (!mDataSource->getUInt64(offset, &tmp)) {
4147 return ERROR_IO;
4148 }
4149 mCurrentSampleInfoOffsets[i] = tmp;
4150 offset += 8;
4151 }
4152 }
4153
4154 // parse clear/encrypted data
4155
4156 off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
4157
4158 drmoffset += mCurrentMoofOffset;
4159 int ivlength;
4160 CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
4161
4162 // only 0, 8 and 16 byte initialization vectors are supported
4163 if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
4164 ALOGW("unsupported IV length: %d", ivlength);
4165 return ERROR_MALFORMED;
4166 }
4167 // read CencSampleAuxiliaryDataFormats
4168 for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
4169 if (i >= mCurrentSamples.size()) {
4170 ALOGW("too few samples");
4171 break;
4172 }
4173 Sample *smpl = &mCurrentSamples.editItemAt(i);
4174
4175 memset(smpl->iv, 0, 16);
4176 if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) {
4177 return ERROR_IO;
4178 }
4179
4180 drmoffset += ivlength;
4181
4182 int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
4183 if (smplinfosize == 0) {
4184 smplinfosize = mCurrentSampleInfoSizes[i];
4185 }
4186 if (smplinfosize > ivlength) {
4187 uint16_t numsubsamples;
4188 if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
4189 return ERROR_IO;
4190 }
4191 drmoffset += 2;
4192 for (size_t j = 0; j < numsubsamples; j++) {
4193 uint16_t numclear;
4194 uint32_t numencrypted;
4195 if (!mDataSource->getUInt16(drmoffset, &numclear)) {
4196 return ERROR_IO;
4197 }
4198 drmoffset += 2;
4199 if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
4200 return ERROR_IO;
4201 }
4202 drmoffset += 4;
4203 smpl->clearsizes.add(numclear);
4204 smpl->encryptedsizes.add(numencrypted);
4205 }
4206 } else {
4207 smpl->clearsizes.add(0);
4208 smpl->encryptedsizes.add(smpl->size);
4209 }
4210 }
4211
4212
4213 return OK;
4214 }
4215
parseTrackFragmentHeader(off64_t offset,off64_t size)4216 status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
4217
4218 if (size < 8) {
4219 return -EINVAL;
4220 }
4221
4222 uint32_t flags;
4223 if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
4224 return ERROR_MALFORMED;
4225 }
4226
4227 if (flags & 0xff000000) {
4228 return -EINVAL;
4229 }
4230
4231 if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
4232 return ERROR_MALFORMED;
4233 }
4234
4235 if (mLastParsedTrackId != mTrackId) {
4236 // this is not the right track, skip it
4237 return OK;
4238 }
4239
4240 mTrackFragmentHeaderInfo.mFlags = flags;
4241 mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
4242 offset += 8;
4243 size -= 8;
4244
4245 ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
4246
4247 if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
4248 if (size < 8) {
4249 return -EINVAL;
4250 }
4251
4252 if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
4253 return ERROR_MALFORMED;
4254 }
4255 offset += 8;
4256 size -= 8;
4257 }
4258
4259 if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
4260 if (size < 4) {
4261 return -EINVAL;
4262 }
4263
4264 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
4265 return ERROR_MALFORMED;
4266 }
4267 offset += 4;
4268 size -= 4;
4269 }
4270
4271 if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
4272 if (size < 4) {
4273 return -EINVAL;
4274 }
4275
4276 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
4277 return ERROR_MALFORMED;
4278 }
4279 offset += 4;
4280 size -= 4;
4281 }
4282
4283 if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
4284 if (size < 4) {
4285 return -EINVAL;
4286 }
4287
4288 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
4289 return ERROR_MALFORMED;
4290 }
4291 offset += 4;
4292 size -= 4;
4293 }
4294
4295 if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
4296 if (size < 4) {
4297 return -EINVAL;
4298 }
4299
4300 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
4301 return ERROR_MALFORMED;
4302 }
4303 offset += 4;
4304 size -= 4;
4305 }
4306
4307 if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
4308 mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
4309 }
4310
4311 mTrackFragmentHeaderInfo.mDataOffset = 0;
4312 return OK;
4313 }
4314
parseTrackFragmentRun(off64_t offset,off64_t size)4315 status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
4316
4317 ALOGV("MPEG4Extractor::parseTrackFragmentRun");
4318 if (size < 8) {
4319 return -EINVAL;
4320 }
4321
4322 enum {
4323 kDataOffsetPresent = 0x01,
4324 kFirstSampleFlagsPresent = 0x04,
4325 kSampleDurationPresent = 0x100,
4326 kSampleSizePresent = 0x200,
4327 kSampleFlagsPresent = 0x400,
4328 kSampleCompositionTimeOffsetPresent = 0x800,
4329 };
4330
4331 uint32_t flags;
4332 if (!mDataSource->getUInt32(offset, &flags)) {
4333 return ERROR_MALFORMED;
4334 }
4335 // |version| only affects SampleCompositionTimeOffset field.
4336 // If version == 0, SampleCompositionTimeOffset is uint32_t;
4337 // Otherwise, SampleCompositionTimeOffset is int32_t.
4338 // Sample.compositionOffset is defined as int32_t.
4339 uint8_t version = flags >> 24;
4340 flags &= 0xffffff;
4341 ALOGV("fragment run version: 0x%02x, flags: 0x%06x", version, flags);
4342
4343 if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
4344 // These two shall not be used together.
4345 return -EINVAL;
4346 }
4347
4348 uint32_t sampleCount;
4349 if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
4350 return ERROR_MALFORMED;
4351 }
4352 offset += 8;
4353 size -= 8;
4354
4355 uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
4356
4357 uint32_t firstSampleFlags = 0;
4358
4359 if (flags & kDataOffsetPresent) {
4360 if (size < 4) {
4361 return -EINVAL;
4362 }
4363
4364 int32_t dataOffsetDelta;
4365 if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) {
4366 return ERROR_MALFORMED;
4367 }
4368
4369 dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
4370
4371 offset += 4;
4372 size -= 4;
4373 }
4374
4375 if (flags & kFirstSampleFlagsPresent) {
4376 if (size < 4) {
4377 return -EINVAL;
4378 }
4379
4380 if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
4381 return ERROR_MALFORMED;
4382 }
4383 offset += 4;
4384 size -= 4;
4385 }
4386
4387 uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
4388 sampleCtsOffset = 0;
4389
4390 size_t bytesPerSample = 0;
4391 if (flags & kSampleDurationPresent) {
4392 bytesPerSample += 4;
4393 } else if (mTrackFragmentHeaderInfo.mFlags
4394 & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
4395 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
4396 } else if (mTrex) {
4397 sampleDuration = mTrex->default_sample_duration;
4398 }
4399
4400 if (flags & kSampleSizePresent) {
4401 bytesPerSample += 4;
4402 } else if (mTrackFragmentHeaderInfo.mFlags
4403 & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
4404 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
4405 } else {
4406 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
4407 }
4408
4409 if (flags & kSampleFlagsPresent) {
4410 bytesPerSample += 4;
4411 } else if (mTrackFragmentHeaderInfo.mFlags
4412 & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
4413 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
4414 } else {
4415 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
4416 }
4417
4418 if (flags & kSampleCompositionTimeOffsetPresent) {
4419 bytesPerSample += 4;
4420 } else {
4421 sampleCtsOffset = 0;
4422 }
4423
4424 if (size < (off64_t)(sampleCount * bytesPerSample)) {
4425 return -EINVAL;
4426 }
4427
4428 Sample tmp;
4429 for (uint32_t i = 0; i < sampleCount; ++i) {
4430 if (flags & kSampleDurationPresent) {
4431 if (!mDataSource->getUInt32(offset, &sampleDuration)) {
4432 return ERROR_MALFORMED;
4433 }
4434 offset += 4;
4435 }
4436
4437 if (flags & kSampleSizePresent) {
4438 if (!mDataSource->getUInt32(offset, &sampleSize)) {
4439 return ERROR_MALFORMED;
4440 }
4441 offset += 4;
4442 }
4443
4444 if (flags & kSampleFlagsPresent) {
4445 if (!mDataSource->getUInt32(offset, &sampleFlags)) {
4446 return ERROR_MALFORMED;
4447 }
4448 offset += 4;
4449 }
4450
4451 if (flags & kSampleCompositionTimeOffsetPresent) {
4452 if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
4453 return ERROR_MALFORMED;
4454 }
4455 offset += 4;
4456 }
4457
4458 ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
4459 " flags 0x%08x", i + 1,
4460 dataOffset, sampleSize, sampleDuration,
4461 (flags & kFirstSampleFlagsPresent) && i == 0
4462 ? firstSampleFlags : sampleFlags);
4463 tmp.offset = dataOffset;
4464 tmp.size = sampleSize;
4465 tmp.duration = sampleDuration;
4466 tmp.compositionOffset = sampleCtsOffset;
4467 mCurrentSamples.add(tmp);
4468
4469 dataOffset += sampleSize;
4470 }
4471
4472 mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
4473
4474 return OK;
4475 }
4476
getFormat()4477 sp<MetaData> MPEG4Source::getFormat() {
4478 Mutex::Autolock autoLock(mLock);
4479
4480 return mFormat;
4481 }
4482
parseNALSize(const uint8_t * data) const4483 size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
4484 switch (mNALLengthSize) {
4485 case 1:
4486 return *data;
4487 case 2:
4488 return U16_AT(data);
4489 case 3:
4490 return ((size_t)data[0] << 16) | U16_AT(&data[1]);
4491 case 4:
4492 return U32_AT(data);
4493 }
4494
4495 // This cannot happen, mNALLengthSize springs to life by adding 1 to
4496 // a 2-bit integer.
4497 CHECK(!"Should not be here.");
4498
4499 return 0;
4500 }
4501
read(MediaBuffer ** out,const ReadOptions * options)4502 status_t MPEG4Source::read(
4503 MediaBuffer **out, const ReadOptions *options) {
4504 Mutex::Autolock autoLock(mLock);
4505
4506 CHECK(mStarted);
4507
4508 if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
4509 *out = nullptr;
4510 return WOULD_BLOCK;
4511 }
4512
4513 if (mFirstMoofOffset > 0) {
4514 return fragmentedRead(out, options);
4515 }
4516
4517 *out = NULL;
4518
4519 int64_t targetSampleTimeUs = -1;
4520
4521 int64_t seekTimeUs;
4522 ReadOptions::SeekMode mode;
4523 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4524 uint32_t findFlags = 0;
4525 switch (mode) {
4526 case ReadOptions::SEEK_PREVIOUS_SYNC:
4527 findFlags = SampleTable::kFlagBefore;
4528 break;
4529 case ReadOptions::SEEK_NEXT_SYNC:
4530 findFlags = SampleTable::kFlagAfter;
4531 break;
4532 case ReadOptions::SEEK_CLOSEST_SYNC:
4533 case ReadOptions::SEEK_CLOSEST:
4534 findFlags = SampleTable::kFlagClosest;
4535 break;
4536 default:
4537 CHECK(!"Should not be here.");
4538 break;
4539 }
4540
4541 uint32_t sampleIndex;
4542 status_t err = mSampleTable->findSampleAtTime(
4543 seekTimeUs, 1000000, mTimescale,
4544 &sampleIndex, findFlags);
4545
4546 if (mode == ReadOptions::SEEK_CLOSEST) {
4547 // We found the closest sample already, now we want the sync
4548 // sample preceding it (or the sample itself of course), even
4549 // if the subsequent sync sample is closer.
4550 findFlags = SampleTable::kFlagBefore;
4551 }
4552
4553 uint32_t syncSampleIndex;
4554 if (err == OK) {
4555 err = mSampleTable->findSyncSampleNear(
4556 sampleIndex, &syncSampleIndex, findFlags);
4557 }
4558
4559 uint32_t sampleTime;
4560 if (err == OK) {
4561 err = mSampleTable->getMetaDataForSample(
4562 sampleIndex, NULL, NULL, &sampleTime);
4563 }
4564
4565 if (err != OK) {
4566 if (err == ERROR_OUT_OF_RANGE) {
4567 // An attempt to seek past the end of the stream would
4568 // normally cause this ERROR_OUT_OF_RANGE error. Propagating
4569 // this all the way to the MediaPlayer would cause abnormal
4570 // termination. Legacy behaviour appears to be to behave as if
4571 // we had seeked to the end of stream, ending normally.
4572 err = ERROR_END_OF_STREAM;
4573 }
4574 ALOGV("end of stream");
4575 return err;
4576 }
4577
4578 if (mode == ReadOptions::SEEK_CLOSEST) {
4579 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
4580 }
4581
4582 #if 0
4583 uint32_t syncSampleTime;
4584 CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
4585 syncSampleIndex, NULL, NULL, &syncSampleTime));
4586
4587 ALOGI("seek to time %lld us => sample at time %lld us, "
4588 "sync sample at time %lld us",
4589 seekTimeUs,
4590 sampleTime * 1000000ll / mTimescale,
4591 syncSampleTime * 1000000ll / mTimescale);
4592 #endif
4593
4594 mCurrentSampleIndex = syncSampleIndex;
4595 if (mBuffer != NULL) {
4596 mBuffer->release();
4597 mBuffer = NULL;
4598 }
4599
4600 // fall through
4601 }
4602
4603 off64_t offset = 0;
4604 size_t size = 0;
4605 uint32_t cts, stts;
4606 bool isSyncSample;
4607 bool newBuffer = false;
4608 if (mBuffer == NULL) {
4609 newBuffer = true;
4610
4611 status_t err =
4612 mSampleTable->getMetaDataForSample(
4613 mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
4614
4615 if (err != OK) {
4616 return err;
4617 }
4618
4619 err = mGroup->acquire_buffer(&mBuffer);
4620
4621 if (err != OK) {
4622 CHECK(mBuffer == NULL);
4623 return err;
4624 }
4625 if (size > mBuffer->size()) {
4626 ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4627 return ERROR_BUFFER_TOO_SMALL;
4628 }
4629 }
4630
4631 if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
4632 if (newBuffer) {
4633 ssize_t num_bytes_read =
4634 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4635
4636 if (num_bytes_read < (ssize_t)size) {
4637 mBuffer->release();
4638 mBuffer = NULL;
4639
4640 return ERROR_IO;
4641 }
4642
4643 CHECK(mBuffer != NULL);
4644 mBuffer->set_range(0, size);
4645 mBuffer->meta_data()->clear();
4646 mBuffer->meta_data()->setInt64(
4647 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4648 mBuffer->meta_data()->setInt64(
4649 kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4650
4651 if (targetSampleTimeUs >= 0) {
4652 mBuffer->meta_data()->setInt64(
4653 kKeyTargetTime, targetSampleTimeUs);
4654 }
4655
4656 if (isSyncSample) {
4657 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
4658 }
4659
4660 ++mCurrentSampleIndex;
4661 }
4662
4663 if (!mIsAVC && !mIsHEVC) {
4664 *out = mBuffer;
4665 mBuffer = NULL;
4666
4667 return OK;
4668 }
4669
4670 // Each NAL unit is split up into its constituent fragments and
4671 // each one of them returned in its own buffer.
4672
4673 CHECK(mBuffer->range_length() >= mNALLengthSize);
4674
4675 const uint8_t *src =
4676 (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
4677
4678 size_t nal_size = parseNALSize(src);
4679 if (mNALLengthSize > SIZE_MAX - nal_size) {
4680 ALOGE("b/24441553, b/24445122");
4681 }
4682 if (mBuffer->range_length() - mNALLengthSize < nal_size) {
4683 ALOGE("incomplete NAL unit.");
4684
4685 mBuffer->release();
4686 mBuffer = NULL;
4687
4688 return ERROR_MALFORMED;
4689 }
4690
4691 MediaBuffer *clone = mBuffer->clone();
4692 CHECK(clone != NULL);
4693 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
4694
4695 CHECK(mBuffer != NULL);
4696 mBuffer->set_range(
4697 mBuffer->range_offset() + mNALLengthSize + nal_size,
4698 mBuffer->range_length() - mNALLengthSize - nal_size);
4699
4700 if (mBuffer->range_length() == 0) {
4701 mBuffer->release();
4702 mBuffer = NULL;
4703 }
4704
4705 *out = clone;
4706
4707 return OK;
4708 } else {
4709 // Whole NAL units are returned but each fragment is prefixed by
4710 // the start code (0x00 00 00 01).
4711 ssize_t num_bytes_read = 0;
4712 int32_t drm = 0;
4713 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
4714 if (usesDRM) {
4715 num_bytes_read =
4716 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
4717 } else {
4718 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
4719 }
4720
4721 if (num_bytes_read < (ssize_t)size) {
4722 mBuffer->release();
4723 mBuffer = NULL;
4724
4725 return ERROR_IO;
4726 }
4727
4728 if (usesDRM) {
4729 CHECK(mBuffer != NULL);
4730 mBuffer->set_range(0, size);
4731
4732 } else {
4733 uint8_t *dstData = (uint8_t *)mBuffer->data();
4734 size_t srcOffset = 0;
4735 size_t dstOffset = 0;
4736
4737 while (srcOffset < size) {
4738 bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
4739 size_t nalLength = 0;
4740 if (!isMalFormed) {
4741 nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
4742 srcOffset += mNALLengthSize;
4743 isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
4744 }
4745
4746 if (isMalFormed) {
4747 ALOGE("Video is malformed");
4748 mBuffer->release();
4749 mBuffer = NULL;
4750 return ERROR_MALFORMED;
4751 }
4752
4753 if (nalLength == 0) {
4754 continue;
4755 }
4756
4757 if (dstOffset > SIZE_MAX - 4 ||
4758 dstOffset + 4 > SIZE_MAX - nalLength ||
4759 dstOffset + 4 + nalLength > mBuffer->size()) {
4760 ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
4761 android_errorWriteLog(0x534e4554, "27208621");
4762 mBuffer->release();
4763 mBuffer = NULL;
4764 return ERROR_MALFORMED;
4765 }
4766
4767 dstData[dstOffset++] = 0;
4768 dstData[dstOffset++] = 0;
4769 dstData[dstOffset++] = 0;
4770 dstData[dstOffset++] = 1;
4771 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
4772 srcOffset += nalLength;
4773 dstOffset += nalLength;
4774 }
4775 CHECK_EQ(srcOffset, size);
4776 CHECK(mBuffer != NULL);
4777 mBuffer->set_range(0, dstOffset);
4778 }
4779
4780 mBuffer->meta_data()->clear();
4781 mBuffer->meta_data()->setInt64(
4782 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4783 mBuffer->meta_data()->setInt64(
4784 kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4785
4786 if (targetSampleTimeUs >= 0) {
4787 mBuffer->meta_data()->setInt64(
4788 kKeyTargetTime, targetSampleTimeUs);
4789 }
4790
4791 if (mIsAVC) {
4792 uint32_t layerId = FindAVCLayerId(
4793 (const uint8_t *)mBuffer->data(), mBuffer->range_length());
4794 mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
4795 }
4796
4797 if (isSyncSample) {
4798 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
4799 }
4800
4801 ++mCurrentSampleIndex;
4802
4803 *out = mBuffer;
4804 mBuffer = NULL;
4805
4806 return OK;
4807 }
4808 }
4809
fragmentedRead(MediaBuffer ** out,const ReadOptions * options)4810 status_t MPEG4Source::fragmentedRead(
4811 MediaBuffer **out, const ReadOptions *options) {
4812
4813 ALOGV("MPEG4Source::fragmentedRead");
4814
4815 CHECK(mStarted);
4816
4817 *out = NULL;
4818
4819 int64_t targetSampleTimeUs = -1;
4820
4821 int64_t seekTimeUs;
4822 ReadOptions::SeekMode mode;
4823 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4824
4825 int numSidxEntries = mSegments.size();
4826 if (numSidxEntries != 0) {
4827 int64_t totalTime = 0;
4828 off64_t totalOffset = mFirstMoofOffset;
4829 for (int i = 0; i < numSidxEntries; i++) {
4830 const SidxEntry *se = &mSegments[i];
4831 if (totalTime + se->mDurationUs > seekTimeUs) {
4832 // The requested time is somewhere in this segment
4833 if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) ||
4834 (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
4835 (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
4836 // requested next sync, or closest sync and it was closer to the end of
4837 // this segment
4838 totalTime += se->mDurationUs;
4839 totalOffset += se->mSize;
4840 }
4841 break;
4842 }
4843 totalTime += se->mDurationUs;
4844 totalOffset += se->mSize;
4845 }
4846 mCurrentMoofOffset = totalOffset;
4847 mNextMoofOffset = -1;
4848 mCurrentSamples.clear();
4849 mCurrentSampleIndex = 0;
4850 status_t err = parseChunk(&totalOffset);
4851 if (err != OK) {
4852 return err;
4853 }
4854 mCurrentTime = totalTime * mTimescale / 1000000ll;
4855 } else {
4856 // without sidx boxes, we can only seek to 0
4857 mCurrentMoofOffset = mFirstMoofOffset;
4858 mNextMoofOffset = -1;
4859 mCurrentSamples.clear();
4860 mCurrentSampleIndex = 0;
4861 off64_t tmp = mCurrentMoofOffset;
4862 status_t err = parseChunk(&tmp);
4863 if (err != OK) {
4864 return err;
4865 }
4866 mCurrentTime = 0;
4867 }
4868
4869 if (mBuffer != NULL) {
4870 mBuffer->release();
4871 mBuffer = NULL;
4872 }
4873
4874 // fall through
4875 }
4876
4877 off64_t offset = 0;
4878 size_t size = 0;
4879 uint32_t cts = 0;
4880 bool isSyncSample = false;
4881 bool newBuffer = false;
4882 if (mBuffer == NULL) {
4883 newBuffer = true;
4884
4885 if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4886 // move to next fragment if there is one
4887 if (mNextMoofOffset <= mCurrentMoofOffset) {
4888 return ERROR_END_OF_STREAM;
4889 }
4890 off64_t nextMoof = mNextMoofOffset;
4891 mCurrentMoofOffset = nextMoof;
4892 mCurrentSamples.clear();
4893 mCurrentSampleIndex = 0;
4894 status_t err = parseChunk(&nextMoof);
4895 if (err != OK) {
4896 return err;
4897 }
4898 if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4899 return ERROR_END_OF_STREAM;
4900 }
4901 }
4902
4903 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
4904 offset = smpl->offset;
4905 size = smpl->size;
4906 cts = mCurrentTime + smpl->compositionOffset;
4907 mCurrentTime += smpl->duration;
4908 isSyncSample = (mCurrentSampleIndex == 0); // XXX
4909
4910 status_t err = mGroup->acquire_buffer(&mBuffer);
4911
4912 if (err != OK) {
4913 CHECK(mBuffer == NULL);
4914 ALOGV("acquire_buffer returned %d", err);
4915 return err;
4916 }
4917 if (size > mBuffer->size()) {
4918 ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4919 return ERROR_BUFFER_TOO_SMALL;
4920 }
4921 }
4922
4923 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
4924 const sp<MetaData> bufmeta = mBuffer->meta_data();
4925 bufmeta->clear();
4926 if (smpl->encryptedsizes.size()) {
4927 // store clear/encrypted lengths in metadata
4928 bufmeta->setData(kKeyPlainSizes, 0,
4929 smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
4930 bufmeta->setData(kKeyEncryptedSizes, 0,
4931 smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
4932 bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
4933 bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
4934 bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
4935 bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
4936 }
4937
4938 if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) {
4939 if (newBuffer) {
4940 if (!isInRange((size_t)0u, mBuffer->size(), size)) {
4941 mBuffer->release();
4942 mBuffer = NULL;
4943
4944 ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
4945 return ERROR_MALFORMED;
4946 }
4947
4948 ssize_t num_bytes_read =
4949 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4950
4951 if (num_bytes_read < (ssize_t)size) {
4952 mBuffer->release();
4953 mBuffer = NULL;
4954
4955 ALOGE("i/o error");
4956 return ERROR_IO;
4957 }
4958
4959 CHECK(mBuffer != NULL);
4960 mBuffer->set_range(0, size);
4961 mBuffer->meta_data()->setInt64(
4962 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4963 mBuffer->meta_data()->setInt64(
4964 kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
4965
4966 if (targetSampleTimeUs >= 0) {
4967 mBuffer->meta_data()->setInt64(
4968 kKeyTargetTime, targetSampleTimeUs);
4969 }
4970
4971 if (mIsAVC) {
4972 uint32_t layerId = FindAVCLayerId(
4973 (const uint8_t *)mBuffer->data(), mBuffer->range_length());
4974 mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
4975 }
4976
4977 if (isSyncSample) {
4978 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
4979 }
4980
4981 ++mCurrentSampleIndex;
4982 }
4983
4984 if (!mIsAVC && !mIsHEVC) {
4985 *out = mBuffer;
4986 mBuffer = NULL;
4987
4988 return OK;
4989 }
4990
4991 // Each NAL unit is split up into its constituent fragments and
4992 // each one of them returned in its own buffer.
4993
4994 CHECK(mBuffer->range_length() >= mNALLengthSize);
4995
4996 const uint8_t *src =
4997 (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
4998
4999 size_t nal_size = parseNALSize(src);
5000 if (mNALLengthSize > SIZE_MAX - nal_size) {
5001 ALOGE("b/24441553, b/24445122");
5002 }
5003
5004 if (mBuffer->range_length() - mNALLengthSize < nal_size) {
5005 ALOGE("incomplete NAL unit.");
5006
5007 mBuffer->release();
5008 mBuffer = NULL;
5009
5010 return ERROR_MALFORMED;
5011 }
5012
5013 MediaBuffer *clone = mBuffer->clone();
5014 CHECK(clone != NULL);
5015 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
5016
5017 CHECK(mBuffer != NULL);
5018 mBuffer->set_range(
5019 mBuffer->range_offset() + mNALLengthSize + nal_size,
5020 mBuffer->range_length() - mNALLengthSize - nal_size);
5021
5022 if (mBuffer->range_length() == 0) {
5023 mBuffer->release();
5024 mBuffer = NULL;
5025 }
5026
5027 *out = clone;
5028
5029 return OK;
5030 } else {
5031 ALOGV("whole NAL");
5032 // Whole NAL units are returned but each fragment is prefixed by
5033 // the start code (0x00 00 00 01).
5034 ssize_t num_bytes_read = 0;
5035 int32_t drm = 0;
5036 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
5037 void *data = NULL;
5038 bool isMalFormed = false;
5039 if (usesDRM) {
5040 if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
5041 isMalFormed = true;
5042 } else {
5043 data = mBuffer->data();
5044 }
5045 } else {
5046 int32_t max_size;
5047 if (mFormat == NULL
5048 || !mFormat->findInt32(kKeyMaxInputSize, &max_size)
5049 || !isInRange((size_t)0u, (size_t)max_size, size)) {
5050 isMalFormed = true;
5051 } else {
5052 data = mSrcBuffer;
5053 }
5054 }
5055
5056 if (isMalFormed || data == NULL) {
5057 ALOGE("isMalFormed size %zu", size);
5058 if (mBuffer != NULL) {
5059 mBuffer->release();
5060 mBuffer = NULL;
5061 }
5062 return ERROR_MALFORMED;
5063 }
5064 num_bytes_read = mDataSource->readAt(offset, data, size);
5065
5066 if (num_bytes_read < (ssize_t)size) {
5067 mBuffer->release();
5068 mBuffer = NULL;
5069
5070 ALOGE("i/o error");
5071 return ERROR_IO;
5072 }
5073
5074 if (usesDRM) {
5075 CHECK(mBuffer != NULL);
5076 mBuffer->set_range(0, size);
5077
5078 } else {
5079 uint8_t *dstData = (uint8_t *)mBuffer->data();
5080 size_t srcOffset = 0;
5081 size_t dstOffset = 0;
5082
5083 while (srcOffset < size) {
5084 isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
5085 size_t nalLength = 0;
5086 if (!isMalFormed) {
5087 nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
5088 srcOffset += mNALLengthSize;
5089 isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
5090 || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
5091 || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
5092 }
5093
5094 if (isMalFormed) {
5095 ALOGE("Video is malformed; nalLength %zu", nalLength);
5096 mBuffer->release();
5097 mBuffer = NULL;
5098 return ERROR_MALFORMED;
5099 }
5100
5101 if (nalLength == 0) {
5102 continue;
5103 }
5104
5105 if (dstOffset > SIZE_MAX - 4 ||
5106 dstOffset + 4 > SIZE_MAX - nalLength ||
5107 dstOffset + 4 + nalLength > mBuffer->size()) {
5108 ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
5109 android_errorWriteLog(0x534e4554, "26365349");
5110 mBuffer->release();
5111 mBuffer = NULL;
5112 return ERROR_MALFORMED;
5113 }
5114
5115 dstData[dstOffset++] = 0;
5116 dstData[dstOffset++] = 0;
5117 dstData[dstOffset++] = 0;
5118 dstData[dstOffset++] = 1;
5119 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
5120 srcOffset += nalLength;
5121 dstOffset += nalLength;
5122 }
5123 CHECK_EQ(srcOffset, size);
5124 CHECK(mBuffer != NULL);
5125 mBuffer->set_range(0, dstOffset);
5126 }
5127
5128 mBuffer->meta_data()->setInt64(
5129 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
5130 mBuffer->meta_data()->setInt64(
5131 kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
5132
5133 if (targetSampleTimeUs >= 0) {
5134 mBuffer->meta_data()->setInt64(
5135 kKeyTargetTime, targetSampleTimeUs);
5136 }
5137
5138 if (isSyncSample) {
5139 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
5140 }
5141
5142 ++mCurrentSampleIndex;
5143
5144 *out = mBuffer;
5145 mBuffer = NULL;
5146
5147 return OK;
5148 }
5149 }
5150
findTrackByMimePrefix(const char * mimePrefix)5151 MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
5152 const char *mimePrefix) {
5153 for (Track *track = mFirstTrack; track != NULL; track = track->next) {
5154 const char *mime;
5155 if (track->meta != NULL
5156 && track->meta->findCString(kKeyMIMEType, &mime)
5157 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
5158 return track;
5159 }
5160 }
5161
5162 return NULL;
5163 }
5164
populateMetrics()5165 void MPEG4Extractor::populateMetrics() {
5166 ALOGV("MPEG4Extractor::populateMetrics");
5167 }
5168
LegacySniffMPEG4(const sp<DataSource> & source,String8 * mimeType,float * confidence)5169 static bool LegacySniffMPEG4(
5170 const sp<DataSource> &source, String8 *mimeType, float *confidence) {
5171 uint8_t header[8];
5172
5173 ssize_t n = source->readAt(4, header, sizeof(header));
5174 if (n < (ssize_t)sizeof(header)) {
5175 return false;
5176 }
5177
5178 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
5179 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
5180 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
5181 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
5182 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
5183 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
5184 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
5185 *confidence = 0.4;
5186
5187 return true;
5188 }
5189
5190 return false;
5191 }
5192
isCompatibleBrand(uint32_t fourcc)5193 static bool isCompatibleBrand(uint32_t fourcc) {
5194 static const uint32_t kCompatibleBrands[] = {
5195 FOURCC('i', 's', 'o', 'm'),
5196 FOURCC('i', 's', 'o', '2'),
5197 FOURCC('a', 'v', 'c', '1'),
5198 FOURCC('h', 'v', 'c', '1'),
5199 FOURCC('h', 'e', 'v', '1'),
5200 FOURCC('3', 'g', 'p', '4'),
5201 FOURCC('m', 'p', '4', '1'),
5202 FOURCC('m', 'p', '4', '2'),
5203
5204 // Won't promise that the following file types can be played.
5205 // Just give these file types a chance.
5206 FOURCC('q', 't', ' ', ' '), // Apple's QuickTime
5207 FOURCC('M', 'S', 'N', 'V'), // Sony's PSP
5208
5209 FOURCC('3', 'g', '2', 'a'), // 3GPP2
5210 FOURCC('3', 'g', '2', 'b'),
5211 };
5212
5213 for (size_t i = 0;
5214 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
5215 ++i) {
5216 if (kCompatibleBrands[i] == fourcc) {
5217 return true;
5218 }
5219 }
5220
5221 return false;
5222 }
5223
5224 // Attempt to actually parse the 'ftyp' atom and determine if a suitable
5225 // compatible brand is present.
5226 // Also try to identify where this file's metadata ends
5227 // (end of the 'moov' atom) and report it to the caller as part of
5228 // the metadata.
BetterSniffMPEG4(const sp<DataSource> & source,String8 * mimeType,float * confidence,sp<AMessage> * meta)5229 static bool BetterSniffMPEG4(
5230 const sp<DataSource> &source, String8 *mimeType, float *confidence,
5231 sp<AMessage> *meta) {
5232 // We scan up to 128 bytes to identify this file as an MP4.
5233 static const off64_t kMaxScanOffset = 128ll;
5234
5235 off64_t offset = 0ll;
5236 bool foundGoodFileType = false;
5237 off64_t moovAtomEndOffset = -1ll;
5238 bool done = false;
5239
5240 while (!done && offset < kMaxScanOffset) {
5241 uint32_t hdr[2];
5242 if (source->readAt(offset, hdr, 8) < 8) {
5243 return false;
5244 }
5245
5246 uint64_t chunkSize = ntohl(hdr[0]);
5247 uint32_t chunkType = ntohl(hdr[1]);
5248 off64_t chunkDataOffset = offset + 8;
5249
5250 if (chunkSize == 1) {
5251 if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
5252 return false;
5253 }
5254
5255 chunkSize = ntoh64(chunkSize);
5256 chunkDataOffset += 8;
5257
5258 if (chunkSize < 16) {
5259 // The smallest valid chunk is 16 bytes long in this case.
5260 return false;
5261 }
5262
5263 } else if (chunkSize < 8) {
5264 // The smallest valid chunk is 8 bytes long.
5265 return false;
5266 }
5267
5268 // (data_offset - offset) is either 8 or 16
5269 off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset);
5270 if (chunkDataSize < 0) {
5271 ALOGE("b/23540914");
5272 return ERROR_MALFORMED;
5273 }
5274
5275 char chunkstring[5];
5276 MakeFourCCString(chunkType, chunkstring);
5277 ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
5278 switch (chunkType) {
5279 case FOURCC('f', 't', 'y', 'p'):
5280 {
5281 if (chunkDataSize < 8) {
5282 return false;
5283 }
5284
5285 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
5286 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
5287 if (i == 1) {
5288 // Skip this index, it refers to the minorVersion,
5289 // not a brand.
5290 continue;
5291 }
5292
5293 uint32_t brand;
5294 if (source->readAt(
5295 chunkDataOffset + 4 * i, &brand, 4) < 4) {
5296 return false;
5297 }
5298
5299 brand = ntohl(brand);
5300
5301 if (isCompatibleBrand(brand)) {
5302 foundGoodFileType = true;
5303 break;
5304 }
5305 }
5306
5307 if (!foundGoodFileType) {
5308 return false;
5309 }
5310
5311 break;
5312 }
5313
5314 case FOURCC('m', 'o', 'o', 'v'):
5315 {
5316 moovAtomEndOffset = offset + chunkSize;
5317
5318 done = true;
5319 break;
5320 }
5321
5322 default:
5323 break;
5324 }
5325
5326 offset += chunkSize;
5327 }
5328
5329 if (!foundGoodFileType) {
5330 return false;
5331 }
5332
5333 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
5334 *confidence = 0.4f;
5335
5336 if (moovAtomEndOffset >= 0) {
5337 *meta = new AMessage;
5338 (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
5339
5340 ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset);
5341 }
5342
5343 return true;
5344 }
5345
SniffMPEG4(const sp<DataSource> & source,String8 * mimeType,float * confidence,sp<AMessage> * meta)5346 bool SniffMPEG4(
5347 const sp<DataSource> &source, String8 *mimeType, float *confidence,
5348 sp<AMessage> *meta) {
5349 if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
5350 return true;
5351 }
5352
5353 if (LegacySniffMPEG4(source, mimeType, confidence)) {
5354 ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
5355 return true;
5356 }
5357
5358 return false;
5359 }
5360
5361 } // namespace android
5362