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 #include <utils/Log.h>
20
21 #include "include/MPEG4Extractor.h"
22 #include "include/SampleTable.h"
23 #include "include/ESDS.h"
24
25 #include <ctype.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <media/stagefright/foundation/ABitReader.h>
31 #include <media/stagefright/foundation/ABuffer.h>
32 #include <media/stagefright/foundation/ADebug.h>
33 #include <media/stagefright/foundation/AMessage.h>
34 #include <media/stagefright/MediaBuffer.h>
35 #include <media/stagefright/MediaBufferGroup.h>
36 #include <media/stagefright/MediaDefs.h>
37 #include <media/stagefright/MediaSource.h>
38 #include <media/stagefright/MetaData.h>
39 #include <utils/String8.h>
40
41 namespace android {
42
43 class MPEG4Source : public MediaSource {
44 public:
45 // Caller retains ownership of both "dataSource" and "sampleTable".
46 MPEG4Source(const sp<MetaData> &format,
47 const sp<DataSource> &dataSource,
48 int32_t timeScale,
49 const sp<SampleTable> &sampleTable,
50 Vector<SidxEntry> &sidx,
51 off64_t firstMoofOffset);
52
53 virtual status_t start(MetaData *params = NULL);
54 virtual status_t stop();
55
56 virtual sp<MetaData> getFormat();
57
58 virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
59 virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL);
60
61 protected:
62 virtual ~MPEG4Source();
63
64 private:
65 Mutex mLock;
66
67 sp<MetaData> mFormat;
68 sp<DataSource> mDataSource;
69 int32_t mTimescale;
70 sp<SampleTable> mSampleTable;
71 uint32_t mCurrentSampleIndex;
72 uint32_t mCurrentFragmentIndex;
73 Vector<SidxEntry> &mSegments;
74 off64_t mFirstMoofOffset;
75 off64_t mCurrentMoofOffset;
76 off64_t mNextMoofOffset;
77 uint32_t mCurrentTime;
78 int32_t mLastParsedTrackId;
79 int32_t mTrackId;
80
81 int32_t mCryptoMode; // passed in from extractor
82 int32_t mDefaultIVSize; // passed in from extractor
83 uint8_t mCryptoKey[16]; // passed in from extractor
84 uint32_t mCurrentAuxInfoType;
85 uint32_t mCurrentAuxInfoTypeParameter;
86 int32_t mCurrentDefaultSampleInfoSize;
87 uint32_t mCurrentSampleInfoCount;
88 uint32_t mCurrentSampleInfoAllocSize;
89 uint8_t* mCurrentSampleInfoSizes;
90 uint32_t mCurrentSampleInfoOffsetCount;
91 uint32_t mCurrentSampleInfoOffsetsAllocSize;
92 uint64_t* mCurrentSampleInfoOffsets;
93
94 bool mIsAVC;
95 size_t mNALLengthSize;
96
97 bool mStarted;
98
99 MediaBufferGroup *mGroup;
100
101 MediaBuffer *mBuffer;
102
103 bool mWantsNALFragments;
104
105 uint8_t *mSrcBuffer;
106
107 size_t parseNALSize(const uint8_t *data) const;
108 status_t parseChunk(off64_t *offset);
109 status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
110 status_t parseTrackFragmentRun(off64_t offset, off64_t size);
111 status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
112 status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
113
114 struct TrackFragmentHeaderInfo {
115 enum Flags {
116 kBaseDataOffsetPresent = 0x01,
117 kSampleDescriptionIndexPresent = 0x02,
118 kDefaultSampleDurationPresent = 0x08,
119 kDefaultSampleSizePresent = 0x10,
120 kDefaultSampleFlagsPresent = 0x20,
121 kDurationIsEmpty = 0x10000,
122 };
123
124 uint32_t mTrackID;
125 uint32_t mFlags;
126 uint64_t mBaseDataOffset;
127 uint32_t mSampleDescriptionIndex;
128 uint32_t mDefaultSampleDuration;
129 uint32_t mDefaultSampleSize;
130 uint32_t mDefaultSampleFlags;
131
132 uint64_t mDataOffset;
133 };
134 TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
135
136 struct Sample {
137 off64_t offset;
138 size_t size;
139 uint32_t duration;
140 uint8_t iv[16];
141 Vector<size_t> clearsizes;
142 Vector<size_t> encryptedsizes;
143 };
144 Vector<Sample> mCurrentSamples;
145
146 MPEG4Source(const MPEG4Source &);
147 MPEG4Source &operator=(const MPEG4Source &);
148 };
149
150 // This custom data source wraps an existing one and satisfies requests
151 // falling entirely within a cached range from the cache while forwarding
152 // all remaining requests to the wrapped datasource.
153 // This is used to cache the full sampletable metadata for a single track,
154 // possibly wrapping multiple times to cover all tracks, i.e.
155 // Each MPEG4DataSource caches the sampletable metadata for a single track.
156
157 struct MPEG4DataSource : public DataSource {
158 MPEG4DataSource(const sp<DataSource> &source);
159
160 virtual status_t initCheck() const;
161 virtual ssize_t readAt(off64_t offset, void *data, size_t size);
162 virtual status_t getSize(off64_t *size);
163 virtual uint32_t flags();
164
165 status_t setCachedRange(off64_t offset, size_t size);
166
167 protected:
168 virtual ~MPEG4DataSource();
169
170 private:
171 Mutex mLock;
172
173 sp<DataSource> mSource;
174 off64_t mCachedOffset;
175 size_t mCachedSize;
176 uint8_t *mCache;
177
178 void clearCache();
179
180 MPEG4DataSource(const MPEG4DataSource &);
181 MPEG4DataSource &operator=(const MPEG4DataSource &);
182 };
183
MPEG4DataSource(const sp<DataSource> & source)184 MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
185 : mSource(source),
186 mCachedOffset(0),
187 mCachedSize(0),
188 mCache(NULL) {
189 }
190
~MPEG4DataSource()191 MPEG4DataSource::~MPEG4DataSource() {
192 clearCache();
193 }
194
clearCache()195 void MPEG4DataSource::clearCache() {
196 if (mCache) {
197 free(mCache);
198 mCache = NULL;
199 }
200
201 mCachedOffset = 0;
202 mCachedSize = 0;
203 }
204
initCheck() const205 status_t MPEG4DataSource::initCheck() const {
206 return mSource->initCheck();
207 }
208
readAt(off64_t offset,void * data,size_t size)209 ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
210 Mutex::Autolock autoLock(mLock);
211
212 if (offset >= mCachedOffset
213 && offset + size <= mCachedOffset + mCachedSize) {
214 memcpy(data, &mCache[offset - mCachedOffset], size);
215 return size;
216 }
217
218 return mSource->readAt(offset, data, size);
219 }
220
getSize(off64_t * size)221 status_t MPEG4DataSource::getSize(off64_t *size) {
222 return mSource->getSize(size);
223 }
224
flags()225 uint32_t MPEG4DataSource::flags() {
226 return mSource->flags();
227 }
228
setCachedRange(off64_t offset,size_t size)229 status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) {
230 Mutex::Autolock autoLock(mLock);
231
232 clearCache();
233
234 mCache = (uint8_t *)malloc(size);
235
236 if (mCache == NULL) {
237 return -ENOMEM;
238 }
239
240 mCachedOffset = offset;
241 mCachedSize = size;
242
243 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
244
245 if (err < (ssize_t)size) {
246 clearCache();
247
248 return ERROR_IO;
249 }
250
251 return OK;
252 }
253
254 ////////////////////////////////////////////////////////////////////////////////
255
hexdump(const void * _data,size_t size)256 static void hexdump(const void *_data, size_t size) {
257 const uint8_t *data = (const uint8_t *)_data;
258 size_t offset = 0;
259 while (offset < size) {
260 printf("0x%04x ", offset);
261
262 size_t n = size - offset;
263 if (n > 16) {
264 n = 16;
265 }
266
267 for (size_t i = 0; i < 16; ++i) {
268 if (i == 8) {
269 printf(" ");
270 }
271
272 if (offset + i < size) {
273 printf("%02x ", data[offset + i]);
274 } else {
275 printf(" ");
276 }
277 }
278
279 printf(" ");
280
281 for (size_t i = 0; i < n; ++i) {
282 if (isprint(data[offset + i])) {
283 printf("%c", data[offset + i]);
284 } else {
285 printf(".");
286 }
287 }
288
289 printf("\n");
290
291 offset += 16;
292 }
293 }
294
FourCC2MIME(uint32_t fourcc)295 static const char *FourCC2MIME(uint32_t fourcc) {
296 switch (fourcc) {
297 case FOURCC('m', 'p', '4', 'a'):
298 return MEDIA_MIMETYPE_AUDIO_AAC;
299
300 case FOURCC('s', 'a', 'm', 'r'):
301 return MEDIA_MIMETYPE_AUDIO_AMR_NB;
302
303 case FOURCC('s', 'a', 'w', 'b'):
304 return MEDIA_MIMETYPE_AUDIO_AMR_WB;
305
306 case FOURCC('m', 'p', '4', 'v'):
307 return MEDIA_MIMETYPE_VIDEO_MPEG4;
308
309 case FOURCC('s', '2', '6', '3'):
310 case FOURCC('h', '2', '6', '3'):
311 case FOURCC('H', '2', '6', '3'):
312 return MEDIA_MIMETYPE_VIDEO_H263;
313
314 case FOURCC('a', 'v', 'c', '1'):
315 return MEDIA_MIMETYPE_VIDEO_AVC;
316
317 default:
318 CHECK(!"should not be here.");
319 return NULL;
320 }
321 }
322
AdjustChannelsAndRate(uint32_t fourcc,uint32_t * channels,uint32_t * rate)323 static bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) {
324 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) {
325 // AMR NB audio is always mono, 8kHz
326 *channels = 1;
327 *rate = 8000;
328 return true;
329 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) {
330 // AMR WB audio is always mono, 16kHz
331 *channels = 1;
332 *rate = 16000;
333 return true;
334 }
335 return false;
336 }
337
MPEG4Extractor(const sp<DataSource> & source)338 MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
339 : mSidxDuration(0),
340 mMoofOffset(0),
341 mDataSource(source),
342 mInitCheck(NO_INIT),
343 mHasVideo(false),
344 mFirstTrack(NULL),
345 mLastTrack(NULL),
346 mFileMetaData(new MetaData),
347 mFirstSINF(NULL),
348 mIsDrm(false) {
349 }
350
~MPEG4Extractor()351 MPEG4Extractor::~MPEG4Extractor() {
352 Track *track = mFirstTrack;
353 while (track) {
354 Track *next = track->next;
355
356 delete track;
357 track = next;
358 }
359 mFirstTrack = mLastTrack = NULL;
360
361 SINF *sinf = mFirstSINF;
362 while (sinf) {
363 SINF *next = sinf->next;
364 delete sinf->IPMPData;
365 delete sinf;
366 sinf = next;
367 }
368 mFirstSINF = NULL;
369
370 for (size_t i = 0; i < mPssh.size(); i++) {
371 delete [] mPssh[i].data;
372 }
373 }
374
flags() const375 uint32_t MPEG4Extractor::flags() const {
376 return CAN_PAUSE |
377 ((mMoofOffset == 0 || mSidxEntries.size() != 0) ?
378 (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
379 }
380
getMetaData()381 sp<MetaData> MPEG4Extractor::getMetaData() {
382 status_t err;
383 if ((err = readMetaData()) != OK) {
384 return new MetaData;
385 }
386
387 return mFileMetaData;
388 }
389
countTracks()390 size_t MPEG4Extractor::countTracks() {
391 status_t err;
392 if ((err = readMetaData()) != OK) {
393 ALOGV("MPEG4Extractor::countTracks: no tracks");
394 return 0;
395 }
396
397 size_t n = 0;
398 Track *track = mFirstTrack;
399 while (track) {
400 ++n;
401 track = track->next;
402 }
403
404 ALOGV("MPEG4Extractor::countTracks: %d tracks", n);
405 return n;
406 }
407
getTrackMetaData(size_t index,uint32_t flags)408 sp<MetaData> MPEG4Extractor::getTrackMetaData(
409 size_t index, uint32_t flags) {
410 status_t err;
411 if ((err = readMetaData()) != OK) {
412 return NULL;
413 }
414
415 Track *track = mFirstTrack;
416 while (index > 0) {
417 if (track == NULL) {
418 return NULL;
419 }
420
421 track = track->next;
422 --index;
423 }
424
425 if (track == NULL) {
426 return NULL;
427 }
428
429 if ((flags & kIncludeExtensiveMetaData)
430 && !track->includes_expensive_metadata) {
431 track->includes_expensive_metadata = true;
432
433 const char *mime;
434 CHECK(track->meta->findCString(kKeyMIMEType, &mime));
435 if (!strncasecmp("video/", mime, 6)) {
436 if (mMoofOffset > 0) {
437 int64_t duration;
438 if (track->meta->findInt64(kKeyDuration, &duration)) {
439 // nothing fancy, just pick a frame near 1/4th of the duration
440 track->meta->setInt64(
441 kKeyThumbnailTime, duration / 4);
442 }
443 } else {
444 uint32_t sampleIndex;
445 uint32_t sampleTime;
446 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
447 && track->sampleTable->getMetaDataForSample(
448 sampleIndex, NULL /* offset */, NULL /* size */,
449 &sampleTime) == OK) {
450 track->meta->setInt64(
451 kKeyThumbnailTime,
452 ((int64_t)sampleTime * 1000000) / track->timescale);
453 }
454 }
455 }
456 }
457
458 return track->meta;
459 }
460
MakeFourCCString(uint32_t x,char * s)461 static void MakeFourCCString(uint32_t x, char *s) {
462 s[0] = x >> 24;
463 s[1] = (x >> 16) & 0xff;
464 s[2] = (x >> 8) & 0xff;
465 s[3] = x & 0xff;
466 s[4] = '\0';
467 }
468
readMetaData()469 status_t MPEG4Extractor::readMetaData() {
470 if (mInitCheck != NO_INIT) {
471 return mInitCheck;
472 }
473
474 off64_t offset = 0;
475 status_t err;
476 while (true) {
477 err = parseChunk(&offset, 0);
478 if (err == OK) {
479 continue;
480 }
481
482 uint32_t hdr[2];
483 if (mDataSource->readAt(offset, hdr, 8) < 8) {
484 break;
485 }
486 uint32_t chunk_type = ntohl(hdr[1]);
487 if (chunk_type == FOURCC('s', 'i', 'd', 'x')) {
488 // parse the sidx box too
489 continue;
490 } else if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
491 // store the offset of the first segment
492 mMoofOffset = offset;
493 }
494 break;
495 }
496
497 if (mInitCheck == OK) {
498 if (mHasVideo) {
499 mFileMetaData->setCString(
500 kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
501 } else {
502 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
503 }
504
505 mInitCheck = OK;
506 } else {
507 mInitCheck = err;
508 }
509
510 CHECK_NE(err, (status_t)NO_INIT);
511
512 // copy pssh data into file metadata
513 int psshsize = 0;
514 for (size_t i = 0; i < mPssh.size(); i++) {
515 psshsize += 20 + mPssh[i].datalen;
516 }
517 if (psshsize) {
518 char *buf = (char*)malloc(psshsize);
519 char *ptr = buf;
520 for (size_t i = 0; i < mPssh.size(); i++) {
521 memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
522 memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
523 ptr += (20 + mPssh[i].datalen);
524 }
525 mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize);
526 free(buf);
527 }
528 return mInitCheck;
529 }
530
getDrmTrackInfo(size_t trackID,int * len)531 char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
532 if (mFirstSINF == NULL) {
533 return NULL;
534 }
535
536 SINF *sinf = mFirstSINF;
537 while (sinf && (trackID != sinf->trackID)) {
538 sinf = sinf->next;
539 }
540
541 if (sinf == NULL) {
542 return NULL;
543 }
544
545 *len = sinf->len;
546 return sinf->IPMPData;
547 }
548
549 // 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)550 static int32_t readSize(off64_t offset,
551 const sp<DataSource> DataSource, uint8_t *numOfBytes) {
552 uint32_t size = 0;
553 uint8_t data;
554 bool moreData = true;
555 *numOfBytes = 0;
556
557 while (moreData) {
558 if (DataSource->readAt(offset, &data, 1) < 1) {
559 return -1;
560 }
561 offset ++;
562 moreData = (data >= 128) ? true : false;
563 size = (size << 7) | (data & 0x7f); // Take last 7 bits
564 (*numOfBytes) ++;
565 }
566
567 return size;
568 }
569
parseDrmSINF(off64_t * offset,off64_t data_offset)570 status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
571 uint8_t updateIdTag;
572 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
573 return ERROR_IO;
574 }
575 data_offset ++;
576
577 if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
578 return ERROR_MALFORMED;
579 }
580
581 uint8_t numOfBytes;
582 int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
583 if (size < 0) {
584 return ERROR_IO;
585 }
586 int32_t classSize = size;
587 data_offset += numOfBytes;
588
589 while(size >= 11 ) {
590 uint8_t descriptorTag;
591 if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
592 return ERROR_IO;
593 }
594 data_offset ++;
595
596 if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
597 return ERROR_MALFORMED;
598 }
599
600 uint8_t buffer[8];
601 //ObjectDescriptorID and ObjectDescriptor url flag
602 if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
603 return ERROR_IO;
604 }
605 data_offset += 2;
606
607 if ((buffer[1] >> 5) & 0x0001) { //url flag is set
608 return ERROR_MALFORMED;
609 }
610
611 if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
612 return ERROR_IO;
613 }
614 data_offset += 8;
615
616 if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
617 || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
618 return ERROR_MALFORMED;
619 }
620
621 SINF *sinf = new SINF;
622 sinf->trackID = U16_AT(&buffer[3]);
623 sinf->IPMPDescriptorID = buffer[7];
624 sinf->next = mFirstSINF;
625 mFirstSINF = sinf;
626
627 size -= (8 + 2 + 1);
628 }
629
630 if (size != 0) {
631 return ERROR_MALFORMED;
632 }
633
634 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
635 return ERROR_IO;
636 }
637 data_offset ++;
638
639 if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
640 return ERROR_MALFORMED;
641 }
642
643 size = readSize(data_offset, mDataSource, &numOfBytes);
644 if (size < 0) {
645 return ERROR_IO;
646 }
647 classSize = size;
648 data_offset += numOfBytes;
649
650 while (size > 0) {
651 uint8_t tag;
652 int32_t dataLen;
653 if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
654 return ERROR_IO;
655 }
656 data_offset ++;
657
658 if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
659 uint8_t id;
660 dataLen = readSize(data_offset, mDataSource, &numOfBytes);
661 if (dataLen < 0) {
662 return ERROR_IO;
663 } else if (dataLen < 4) {
664 return ERROR_MALFORMED;
665 }
666 data_offset += numOfBytes;
667
668 if (mDataSource->readAt(data_offset, &id, 1) < 1) {
669 return ERROR_IO;
670 }
671 data_offset ++;
672
673 SINF *sinf = mFirstSINF;
674 while (sinf && (sinf->IPMPDescriptorID != id)) {
675 sinf = sinf->next;
676 }
677 if (sinf == NULL) {
678 return ERROR_MALFORMED;
679 }
680 sinf->len = dataLen - 3;
681 sinf->IPMPData = new char[sinf->len];
682
683 if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
684 return ERROR_IO;
685 }
686 data_offset += sinf->len;
687
688 size -= (dataLen + numOfBytes + 1);
689 }
690 }
691
692 if (size != 0) {
693 return ERROR_MALFORMED;
694 }
695
696 return UNKNOWN_ERROR; // Return a dummy error.
697 }
698
699 struct PathAdder {
PathAdderandroid::PathAdder700 PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
701 : mPath(path) {
702 mPath->push(chunkType);
703 }
704
~PathAdderandroid::PathAdder705 ~PathAdder() {
706 mPath->pop();
707 }
708
709 private:
710 Vector<uint32_t> *mPath;
711
712 PathAdder(const PathAdder &);
713 PathAdder &operator=(const PathAdder &);
714 };
715
underMetaDataPath(const Vector<uint32_t> & path)716 static bool underMetaDataPath(const Vector<uint32_t> &path) {
717 return path.size() >= 5
718 && path[0] == FOURCC('m', 'o', 'o', 'v')
719 && path[1] == FOURCC('u', 'd', 't', 'a')
720 && path[2] == FOURCC('m', 'e', 't', 'a')
721 && path[3] == FOURCC('i', 'l', 's', 't');
722 }
723
724 // Given a time in seconds since Jan 1 1904, produce a human-readable string.
convertTimeToDate(int64_t time_1904,String8 * s)725 static void convertTimeToDate(int64_t time_1904, String8 *s) {
726 time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
727
728 char tmp[32];
729 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
730
731 s->setTo(tmp);
732 }
733
parseChunk(off64_t * offset,int depth)734 status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
735 ALOGV("entering parseChunk %lld/%d", *offset, depth);
736 uint32_t hdr[2];
737 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
738 return ERROR_IO;
739 }
740 uint64_t chunk_size = ntohl(hdr[0]);
741 uint32_t chunk_type = ntohl(hdr[1]);
742 off64_t data_offset = *offset + 8;
743
744 if (chunk_size == 1) {
745 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
746 return ERROR_IO;
747 }
748 chunk_size = ntoh64(chunk_size);
749 data_offset += 8;
750
751 if (chunk_size < 16) {
752 // The smallest valid chunk is 16 bytes long in this case.
753 return ERROR_MALFORMED;
754 }
755 } else if (chunk_size < 8) {
756 // The smallest valid chunk is 8 bytes long.
757 return ERROR_MALFORMED;
758 }
759
760 char chunk[5];
761 MakeFourCCString(chunk_type, chunk);
762 ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth);
763
764 #if 0
765 static const char kWhitespace[] = " ";
766 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
767 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
768
769 char buffer[256];
770 size_t n = chunk_size;
771 if (n > sizeof(buffer)) {
772 n = sizeof(buffer);
773 }
774 if (mDataSource->readAt(*offset, buffer, n)
775 < (ssize_t)n) {
776 return ERROR_IO;
777 }
778
779 hexdump(buffer, n);
780 #endif
781
782 PathAdder autoAdder(&mPath, chunk_type);
783
784 off64_t chunk_data_size = *offset + chunk_size - data_offset;
785
786 if (chunk_type != FOURCC('c', 'p', 'r', 't')
787 && chunk_type != FOURCC('c', 'o', 'v', 'r')
788 && mPath.size() == 5 && underMetaDataPath(mPath)) {
789 off64_t stop_offset = *offset + chunk_size;
790 *offset = data_offset;
791 while (*offset < stop_offset) {
792 status_t err = parseChunk(offset, depth + 1);
793 if (err != OK) {
794 return err;
795 }
796 }
797
798 if (*offset != stop_offset) {
799 return ERROR_MALFORMED;
800 }
801
802 return OK;
803 }
804
805 switch(chunk_type) {
806 case FOURCC('m', 'o', 'o', 'v'):
807 case FOURCC('t', 'r', 'a', 'k'):
808 case FOURCC('m', 'd', 'i', 'a'):
809 case FOURCC('m', 'i', 'n', 'f'):
810 case FOURCC('d', 'i', 'n', 'f'):
811 case FOURCC('s', 't', 'b', 'l'):
812 case FOURCC('m', 'v', 'e', 'x'):
813 case FOURCC('m', 'o', 'o', 'f'):
814 case FOURCC('t', 'r', 'a', 'f'):
815 case FOURCC('m', 'f', 'r', 'a'):
816 case FOURCC('u', 'd', 't', 'a'):
817 case FOURCC('i', 'l', 's', 't'):
818 case FOURCC('s', 'i', 'n', 'f'):
819 case FOURCC('s', 'c', 'h', 'i'):
820 {
821 if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
822 ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
823
824 if (mDataSource->flags()
825 & (DataSource::kWantsPrefetching
826 | DataSource::kIsCachingDataSource)) {
827 sp<MPEG4DataSource> cachedSource =
828 new MPEG4DataSource(mDataSource);
829
830 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
831 mDataSource = cachedSource;
832 }
833 }
834
835 mLastTrack->sampleTable = new SampleTable(mDataSource);
836 }
837
838 bool isTrack = false;
839 if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
840 isTrack = true;
841
842 Track *track = new Track;
843 track->next = NULL;
844 if (mLastTrack) {
845 mLastTrack->next = track;
846 } else {
847 mFirstTrack = track;
848 }
849 mLastTrack = track;
850
851 track->meta = new MetaData;
852 track->includes_expensive_metadata = false;
853 track->skipTrack = false;
854 track->timescale = 0;
855 track->meta->setCString(kKeyMIMEType, "application/octet-stream");
856 }
857
858 off64_t stop_offset = *offset + chunk_size;
859 *offset = data_offset;
860 while (*offset < stop_offset) {
861 status_t err = parseChunk(offset, depth + 1);
862 if (err != OK) {
863 return err;
864 }
865 }
866
867 if (*offset != stop_offset) {
868 return ERROR_MALFORMED;
869 }
870
871 if (isTrack) {
872 if (mLastTrack->skipTrack) {
873 Track *cur = mFirstTrack;
874
875 if (cur == mLastTrack) {
876 delete cur;
877 mFirstTrack = mLastTrack = NULL;
878 } else {
879 while (cur && cur->next != mLastTrack) {
880 cur = cur->next;
881 }
882 cur->next = NULL;
883 delete mLastTrack;
884 mLastTrack = cur;
885 }
886
887 return OK;
888 }
889
890 status_t err = verifyTrack(mLastTrack);
891
892 if (err != OK) {
893 return err;
894 }
895 } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
896 mInitCheck = OK;
897
898 if (!mIsDrm) {
899 return UNKNOWN_ERROR; // Return a dummy error.
900 } else {
901 return OK;
902 }
903 }
904 break;
905 }
906
907 case FOURCC('f', 'r', 'm', 'a'):
908 {
909 uint32_t original_fourcc;
910 if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) {
911 return ERROR_IO;
912 }
913 original_fourcc = ntohl(original_fourcc);
914 ALOGV("read original format: %d", original_fourcc);
915 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
916 uint32_t num_channels = 0;
917 uint32_t sample_rate = 0;
918 if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
919 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
920 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
921 }
922 *offset += chunk_size;
923 break;
924 }
925
926 case FOURCC('t', 'e', 'n', 'c'):
927 {
928 if (chunk_size < 32) {
929 return ERROR_MALFORMED;
930 }
931
932 // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte
933 // default IV size, 16 bytes default KeyID
934 // (ISO 23001-7)
935 char buf[4];
936 memset(buf, 0, 4);
937 if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) {
938 return ERROR_IO;
939 }
940 uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf));
941 if (defaultAlgorithmId > 1) {
942 // only 0 (clear) and 1 (AES-128) are valid
943 return ERROR_MALFORMED;
944 }
945
946 memset(buf, 0, 4);
947 if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) {
948 return ERROR_IO;
949 }
950 uint32_t defaultIVSize = ntohl(*((int32_t*)buf));
951
952 if ((defaultAlgorithmId == 0 && defaultIVSize != 0) ||
953 (defaultAlgorithmId != 0 && defaultIVSize == 0)) {
954 // only unencrypted data must have 0 IV size
955 return ERROR_MALFORMED;
956 } else if (defaultIVSize != 0 &&
957 defaultIVSize != 8 &&
958 defaultIVSize != 16) {
959 // only supported sizes are 0, 8 and 16
960 return ERROR_MALFORMED;
961 }
962
963 uint8_t defaultKeyId[16];
964
965 if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) {
966 return ERROR_IO;
967 }
968
969 mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId);
970 mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize);
971 mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16);
972 *offset += chunk_size;
973 break;
974 }
975
976 case FOURCC('t', 'k', 'h', 'd'):
977 {
978 status_t err;
979 if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
980 return err;
981 }
982
983 *offset += chunk_size;
984 break;
985 }
986
987 case FOURCC('p', 's', 's', 'h'):
988 {
989 PsshInfo pssh;
990
991 if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) {
992 return ERROR_IO;
993 }
994
995 uint32_t psshdatalen = 0;
996 if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) {
997 return ERROR_IO;
998 }
999 pssh.datalen = ntohl(psshdatalen);
1000 ALOGV("pssh data size: %d", pssh.datalen);
1001 if (pssh.datalen + 20 > chunk_size) {
1002 // pssh data length exceeds size of containing box
1003 return ERROR_MALFORMED;
1004 }
1005
1006 pssh.data = new uint8_t[pssh.datalen];
1007 ALOGV("allocated pssh @ %p", pssh.data);
1008 ssize_t requested = (ssize_t) pssh.datalen;
1009 if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
1010 return ERROR_IO;
1011 }
1012 mPssh.push_back(pssh);
1013
1014 *offset += chunk_size;
1015 break;
1016 }
1017
1018 case FOURCC('m', 'd', 'h', 'd'):
1019 {
1020 if (chunk_data_size < 4) {
1021 return ERROR_MALFORMED;
1022 }
1023
1024 uint8_t version;
1025 if (mDataSource->readAt(
1026 data_offset, &version, sizeof(version))
1027 < (ssize_t)sizeof(version)) {
1028 return ERROR_IO;
1029 }
1030
1031 off64_t timescale_offset;
1032
1033 if (version == 1) {
1034 timescale_offset = data_offset + 4 + 16;
1035 } else if (version == 0) {
1036 timescale_offset = data_offset + 4 + 8;
1037 } else {
1038 return ERROR_IO;
1039 }
1040
1041 uint32_t timescale;
1042 if (mDataSource->readAt(
1043 timescale_offset, ×cale, sizeof(timescale))
1044 < (ssize_t)sizeof(timescale)) {
1045 return ERROR_IO;
1046 }
1047
1048 mLastTrack->timescale = ntohl(timescale);
1049
1050 int64_t duration = 0;
1051 if (version == 1) {
1052 if (mDataSource->readAt(
1053 timescale_offset + 4, &duration, sizeof(duration))
1054 < (ssize_t)sizeof(duration)) {
1055 return ERROR_IO;
1056 }
1057 duration = ntoh64(duration);
1058 } else {
1059 uint32_t duration32;
1060 if (mDataSource->readAt(
1061 timescale_offset + 4, &duration32, sizeof(duration32))
1062 < (ssize_t)sizeof(duration32)) {
1063 return ERROR_IO;
1064 }
1065 // ffmpeg sets duration to -1, which is incorrect.
1066 if (duration32 != 0xffffffff) {
1067 duration = ntohl(duration32);
1068 }
1069 }
1070 mLastTrack->meta->setInt64(
1071 kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
1072
1073 uint8_t lang[2];
1074 off64_t lang_offset;
1075 if (version == 1) {
1076 lang_offset = timescale_offset + 4 + 8;
1077 } else if (version == 0) {
1078 lang_offset = timescale_offset + 4 + 4;
1079 } else {
1080 return ERROR_IO;
1081 }
1082
1083 if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
1084 < (ssize_t)sizeof(lang)) {
1085 return ERROR_IO;
1086 }
1087
1088 // To get the ISO-639-2/T three character language code
1089 // 1 bit pad followed by 3 5-bits characters. Each character
1090 // is packed as the difference between its ASCII value and 0x60.
1091 char lang_code[4];
1092 lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
1093 lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
1094 lang_code[2] = (lang[1] & 0x1f) + 0x60;
1095 lang_code[3] = '\0';
1096
1097 mLastTrack->meta->setCString(
1098 kKeyMediaLanguage, lang_code);
1099
1100 *offset += chunk_size;
1101 break;
1102 }
1103
1104 case FOURCC('s', 't', 's', 'd'):
1105 {
1106 if (chunk_data_size < 8) {
1107 return ERROR_MALFORMED;
1108 }
1109
1110 uint8_t buffer[8];
1111 if (chunk_data_size < (off64_t)sizeof(buffer)) {
1112 return ERROR_MALFORMED;
1113 }
1114
1115 if (mDataSource->readAt(
1116 data_offset, buffer, 8) < 8) {
1117 return ERROR_IO;
1118 }
1119
1120 if (U32_AT(buffer) != 0) {
1121 // Should be version 0, flags 0.
1122 return ERROR_MALFORMED;
1123 }
1124
1125 uint32_t entry_count = U32_AT(&buffer[4]);
1126
1127 if (entry_count > 1) {
1128 // For 3GPP timed text, there could be multiple tx3g boxes contain
1129 // multiple text display formats. These formats will be used to
1130 // display the timed text.
1131 // For encrypted files, there may also be more than one entry.
1132 const char *mime;
1133 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1134 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
1135 strcasecmp(mime, "application/octet-stream")) {
1136 // For now we only support a single type of media per track.
1137 mLastTrack->skipTrack = true;
1138 *offset += chunk_size;
1139 break;
1140 }
1141 }
1142 off64_t stop_offset = *offset + chunk_size;
1143 *offset = data_offset + 8;
1144 for (uint32_t i = 0; i < entry_count; ++i) {
1145 status_t err = parseChunk(offset, depth + 1);
1146 if (err != OK) {
1147 return err;
1148 }
1149 }
1150
1151 if (*offset != stop_offset) {
1152 return ERROR_MALFORMED;
1153 }
1154 break;
1155 }
1156
1157 case FOURCC('m', 'p', '4', 'a'):
1158 case FOURCC('e', 'n', 'c', 'a'):
1159 case FOURCC('s', 'a', 'm', 'r'):
1160 case FOURCC('s', 'a', 'w', 'b'):
1161 {
1162 uint8_t buffer[8 + 20];
1163 if (chunk_data_size < (ssize_t)sizeof(buffer)) {
1164 // Basic AudioSampleEntry size.
1165 return ERROR_MALFORMED;
1166 }
1167
1168 if (mDataSource->readAt(
1169 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
1170 return ERROR_IO;
1171 }
1172
1173 uint16_t data_ref_index = U16_AT(&buffer[6]);
1174 uint32_t num_channels = U16_AT(&buffer[16]);
1175
1176 uint16_t sample_size = U16_AT(&buffer[18]);
1177 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
1178
1179 if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
1180 // if the chunk type is enca, we'll get the type from the sinf/frma box later
1181 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1182 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
1183 }
1184 ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
1185 chunk, num_channels, sample_size, sample_rate);
1186 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
1187 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
1188
1189 off64_t stop_offset = *offset + chunk_size;
1190 *offset = data_offset + sizeof(buffer);
1191 while (*offset < stop_offset) {
1192 status_t err = parseChunk(offset, depth + 1);
1193 if (err != OK) {
1194 return err;
1195 }
1196 }
1197
1198 if (*offset != stop_offset) {
1199 return ERROR_MALFORMED;
1200 }
1201 break;
1202 }
1203
1204 case FOURCC('m', 'p', '4', 'v'):
1205 case FOURCC('e', 'n', 'c', 'v'):
1206 case FOURCC('s', '2', '6', '3'):
1207 case FOURCC('H', '2', '6', '3'):
1208 case FOURCC('h', '2', '6', '3'):
1209 case FOURCC('a', 'v', 'c', '1'):
1210 {
1211 mHasVideo = true;
1212
1213 uint8_t buffer[78];
1214 if (chunk_data_size < (ssize_t)sizeof(buffer)) {
1215 // Basic VideoSampleEntry size.
1216 return ERROR_MALFORMED;
1217 }
1218
1219 if (mDataSource->readAt(
1220 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
1221 return ERROR_IO;
1222 }
1223
1224 uint16_t data_ref_index = U16_AT(&buffer[6]);
1225 uint16_t width = U16_AT(&buffer[6 + 18]);
1226 uint16_t height = U16_AT(&buffer[6 + 20]);
1227
1228 // The video sample is not standard-compliant if it has invalid dimension.
1229 // Use some default width and height value, and
1230 // let the decoder figure out the actual width and height (and thus
1231 // be prepared for INFO_FOMRAT_CHANGED event).
1232 if (width == 0) width = 352;
1233 if (height == 0) height = 288;
1234
1235 // printf("*** coding='%s' width=%d height=%d\n",
1236 // chunk, width, height);
1237
1238 if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
1239 // if the chunk type is encv, we'll get the type from the sinf/frma box later
1240 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1241 }
1242 mLastTrack->meta->setInt32(kKeyWidth, width);
1243 mLastTrack->meta->setInt32(kKeyHeight, height);
1244
1245 off64_t stop_offset = *offset + chunk_size;
1246 *offset = data_offset + sizeof(buffer);
1247 while (*offset < stop_offset) {
1248 status_t err = parseChunk(offset, depth + 1);
1249 if (err != OK) {
1250 return err;
1251 }
1252 }
1253
1254 if (*offset != stop_offset) {
1255 return ERROR_MALFORMED;
1256 }
1257 break;
1258 }
1259
1260 case FOURCC('s', 't', 'c', 'o'):
1261 case FOURCC('c', 'o', '6', '4'):
1262 {
1263 status_t err =
1264 mLastTrack->sampleTable->setChunkOffsetParams(
1265 chunk_type, data_offset, chunk_data_size);
1266
1267 if (err != OK) {
1268 return err;
1269 }
1270
1271 *offset += chunk_size;
1272 break;
1273 }
1274
1275 case FOURCC('s', 't', 's', 'c'):
1276 {
1277 status_t err =
1278 mLastTrack->sampleTable->setSampleToChunkParams(
1279 data_offset, chunk_data_size);
1280
1281 if (err != OK) {
1282 return err;
1283 }
1284
1285 *offset += chunk_size;
1286 break;
1287 }
1288
1289 case FOURCC('s', 't', 's', 'z'):
1290 case FOURCC('s', 't', 'z', '2'):
1291 {
1292 status_t err =
1293 mLastTrack->sampleTable->setSampleSizeParams(
1294 chunk_type, data_offset, chunk_data_size);
1295
1296 if (err != OK) {
1297 return err;
1298 }
1299
1300 size_t max_size;
1301 err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
1302
1303 if (err != OK) {
1304 return err;
1305 }
1306
1307 if (max_size != 0) {
1308 // Assume that a given buffer only contains at most 10 chunks,
1309 // each chunk originally prefixed with a 2 byte length will
1310 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
1311 // and thus will grow by 2 bytes per chunk.
1312 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
1313 } else {
1314 // No size was specified. Pick a conservatively large size.
1315 int32_t width, height;
1316 if (mLastTrack->meta->findInt32(kKeyWidth, &width) &&
1317 mLastTrack->meta->findInt32(kKeyHeight, &height)) {
1318 mLastTrack->meta->setInt32(kKeyMaxInputSize, width * height * 3 / 2);
1319 } else {
1320 ALOGE("No width or height, assuming worst case 1080p");
1321 mLastTrack->meta->setInt32(kKeyMaxInputSize, 3110400);
1322 }
1323 }
1324 *offset += chunk_size;
1325
1326 // Calculate average frame rate.
1327 const char *mime;
1328 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1329 if (!strncasecmp("video/", mime, 6)) {
1330 size_t nSamples = mLastTrack->sampleTable->countSamples();
1331 int64_t durationUs;
1332 if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
1333 if (durationUs > 0) {
1334 int32_t frameRate = (nSamples * 1000000LL +
1335 (durationUs >> 1)) / durationUs;
1336 mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1337 }
1338 }
1339 }
1340
1341 break;
1342 }
1343
1344 case FOURCC('s', 't', 't', 's'):
1345 {
1346 status_t err =
1347 mLastTrack->sampleTable->setTimeToSampleParams(
1348 data_offset, chunk_data_size);
1349
1350 if (err != OK) {
1351 return err;
1352 }
1353
1354 *offset += chunk_size;
1355 break;
1356 }
1357
1358 case FOURCC('c', 't', 't', 's'):
1359 {
1360 status_t err =
1361 mLastTrack->sampleTable->setCompositionTimeToSampleParams(
1362 data_offset, chunk_data_size);
1363
1364 if (err != OK) {
1365 return err;
1366 }
1367
1368 *offset += chunk_size;
1369 break;
1370 }
1371
1372 case FOURCC('s', 't', 's', 's'):
1373 {
1374 status_t err =
1375 mLastTrack->sampleTable->setSyncSampleParams(
1376 data_offset, chunk_data_size);
1377
1378 if (err != OK) {
1379 return err;
1380 }
1381
1382 *offset += chunk_size;
1383 break;
1384 }
1385
1386 // @xyz
1387 case FOURCC('\xA9', 'x', 'y', 'z'):
1388 {
1389 // Best case the total data length inside "@xyz" box
1390 // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/",
1391 // where "\x00\x04" is the text string length with value = 4,
1392 // "\0x15\xc7" is the language code = en, and "0+0" is a
1393 // location (string) value with longitude = 0 and latitude = 0.
1394 if (chunk_data_size < 8) {
1395 return ERROR_MALFORMED;
1396 }
1397
1398 // Worst case the location string length would be 18,
1399 // for instance +90.0000-180.0000, without the trailing "/" and
1400 // the string length + language code.
1401 char buffer[18];
1402
1403 // Substracting 5 from the data size is because the text string length +
1404 // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
1405 off64_t location_length = chunk_data_size - 5;
1406 if (location_length >= (off64_t) sizeof(buffer)) {
1407 return ERROR_MALFORMED;
1408 }
1409
1410 if (mDataSource->readAt(
1411 data_offset + 4, buffer, location_length) < location_length) {
1412 return ERROR_IO;
1413 }
1414
1415 buffer[location_length] = '\0';
1416 mFileMetaData->setCString(kKeyLocation, buffer);
1417 *offset += chunk_size;
1418 break;
1419 }
1420
1421 case FOURCC('e', 's', 'd', 's'):
1422 {
1423 if (chunk_data_size < 4) {
1424 return ERROR_MALFORMED;
1425 }
1426
1427 uint8_t buffer[256];
1428 if (chunk_data_size > (off64_t)sizeof(buffer)) {
1429 return ERROR_BUFFER_TOO_SMALL;
1430 }
1431
1432 if (mDataSource->readAt(
1433 data_offset, buffer, chunk_data_size) < chunk_data_size) {
1434 return ERROR_IO;
1435 }
1436
1437 if (U32_AT(buffer) != 0) {
1438 // Should be version 0, flags 0.
1439 return ERROR_MALFORMED;
1440 }
1441
1442 mLastTrack->meta->setData(
1443 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
1444
1445 if (mPath.size() >= 2
1446 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1447 // Information from the ESDS must be relied on for proper
1448 // setup of sample rate and channel count for MPEG4 Audio.
1449 // The generic header appears to only contain generic
1450 // information...
1451
1452 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1453 &buffer[4], chunk_data_size - 4);
1454
1455 if (err != OK) {
1456 return err;
1457 }
1458 }
1459
1460 *offset += chunk_size;
1461 break;
1462 }
1463
1464 case FOURCC('a', 'v', 'c', 'C'):
1465 {
1466 sp<ABuffer> buffer = new ABuffer(chunk_data_size);
1467
1468 if (mDataSource->readAt(
1469 data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
1470 return ERROR_IO;
1471 }
1472
1473 mLastTrack->meta->setData(
1474 kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size);
1475
1476 *offset += chunk_size;
1477 break;
1478 }
1479
1480 case FOURCC('d', '2', '6', '3'):
1481 {
1482 /*
1483 * d263 contains a fixed 7 bytes part:
1484 * vendor - 4 bytes
1485 * version - 1 byte
1486 * level - 1 byte
1487 * profile - 1 byte
1488 * optionally, "d263" box itself may contain a 16-byte
1489 * bit rate box (bitr)
1490 * average bit rate - 4 bytes
1491 * max bit rate - 4 bytes
1492 */
1493 char buffer[23];
1494 if (chunk_data_size != 7 &&
1495 chunk_data_size != 23) {
1496 ALOGE("Incorrect D263 box size %lld", chunk_data_size);
1497 return ERROR_MALFORMED;
1498 }
1499
1500 if (mDataSource->readAt(
1501 data_offset, buffer, chunk_data_size) < chunk_data_size) {
1502 return ERROR_IO;
1503 }
1504
1505 mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
1506
1507 *offset += chunk_size;
1508 break;
1509 }
1510
1511 case FOURCC('m', 'e', 't', 'a'):
1512 {
1513 uint8_t buffer[4];
1514 if (chunk_data_size < (off64_t)sizeof(buffer)) {
1515 return ERROR_MALFORMED;
1516 }
1517
1518 if (mDataSource->readAt(
1519 data_offset, buffer, 4) < 4) {
1520 return ERROR_IO;
1521 }
1522
1523 if (U32_AT(buffer) != 0) {
1524 // Should be version 0, flags 0.
1525
1526 // If it's not, let's assume this is one of those
1527 // apparently malformed chunks that don't have flags
1528 // and completely different semantics than what's
1529 // in the MPEG4 specs and skip it.
1530 *offset += chunk_size;
1531 return OK;
1532 }
1533
1534 off64_t stop_offset = *offset + chunk_size;
1535 *offset = data_offset + sizeof(buffer);
1536 while (*offset < stop_offset) {
1537 status_t err = parseChunk(offset, depth + 1);
1538 if (err != OK) {
1539 return err;
1540 }
1541 }
1542
1543 if (*offset != stop_offset) {
1544 return ERROR_MALFORMED;
1545 }
1546 break;
1547 }
1548
1549 case FOURCC('m', 'e', 'a', 'n'):
1550 case FOURCC('n', 'a', 'm', 'e'):
1551 case FOURCC('d', 'a', 't', 'a'):
1552 {
1553 if (mPath.size() == 6 && underMetaDataPath(mPath)) {
1554 status_t err = parseMetaData(data_offset, chunk_data_size);
1555
1556 if (err != OK) {
1557 return err;
1558 }
1559 }
1560
1561 *offset += chunk_size;
1562 break;
1563 }
1564
1565 case FOURCC('m', 'v', 'h', 'd'):
1566 {
1567 if (chunk_data_size < 12) {
1568 return ERROR_MALFORMED;
1569 }
1570
1571 uint8_t header[12];
1572 if (mDataSource->readAt(
1573 data_offset, header, sizeof(header))
1574 < (ssize_t)sizeof(header)) {
1575 return ERROR_IO;
1576 }
1577
1578 int64_t creationTime;
1579 if (header[0] == 1) {
1580 creationTime = U64_AT(&header[4]);
1581 } else if (header[0] != 0) {
1582 return ERROR_MALFORMED;
1583 } else {
1584 creationTime = U32_AT(&header[4]);
1585 }
1586
1587 String8 s;
1588 convertTimeToDate(creationTime, &s);
1589
1590 mFileMetaData->setCString(kKeyDate, s.string());
1591
1592 *offset += chunk_size;
1593 break;
1594 }
1595
1596 case FOURCC('m', 'd', 'a', 't'):
1597 {
1598 ALOGV("mdat chunk, drm: %d", mIsDrm);
1599 if (!mIsDrm) {
1600 *offset += chunk_size;
1601 break;
1602 }
1603
1604 if (chunk_size < 8) {
1605 return ERROR_MALFORMED;
1606 }
1607
1608 return parseDrmSINF(offset, data_offset);
1609 }
1610
1611 case FOURCC('h', 'd', 'l', 'r'):
1612 {
1613 uint32_t buffer;
1614 if (mDataSource->readAt(
1615 data_offset + 8, &buffer, 4) < 4) {
1616 return ERROR_IO;
1617 }
1618
1619 uint32_t type = ntohl(buffer);
1620 // For the 3GPP file format, the handler-type within the 'hdlr' box
1621 // shall be 'text'. We also want to support 'sbtl' handler type
1622 // for a practical reason as various MPEG4 containers use it.
1623 if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
1624 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
1625 }
1626
1627 *offset += chunk_size;
1628 break;
1629 }
1630
1631 case FOURCC('t', 'x', '3', 'g'):
1632 {
1633 uint32_t type;
1634 const void *data;
1635 size_t size = 0;
1636 if (!mLastTrack->meta->findData(
1637 kKeyTextFormatData, &type, &data, &size)) {
1638 size = 0;
1639 }
1640
1641 uint8_t *buffer = new uint8_t[size + chunk_size];
1642
1643 if (size > 0) {
1644 memcpy(buffer, data, size);
1645 }
1646
1647 if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
1648 < chunk_size) {
1649 delete[] buffer;
1650 buffer = NULL;
1651
1652 return ERROR_IO;
1653 }
1654
1655 mLastTrack->meta->setData(
1656 kKeyTextFormatData, 0, buffer, size + chunk_size);
1657
1658 delete[] buffer;
1659
1660 *offset += chunk_size;
1661 break;
1662 }
1663
1664 case FOURCC('c', 'o', 'v', 'r'):
1665 {
1666 if (mFileMetaData != NULL) {
1667 ALOGV("chunk_data_size = %lld and data_offset = %lld",
1668 chunk_data_size, data_offset);
1669 sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
1670 if (mDataSource->readAt(
1671 data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
1672 return ERROR_IO;
1673 }
1674 const int kSkipBytesOfDataBox = 16;
1675 mFileMetaData->setData(
1676 kKeyAlbumArt, MetaData::TYPE_NONE,
1677 buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
1678 }
1679
1680 *offset += chunk_size;
1681 break;
1682 }
1683
1684 case FOURCC('-', '-', '-', '-'):
1685 {
1686 mLastCommentMean.clear();
1687 mLastCommentName.clear();
1688 mLastCommentData.clear();
1689 *offset += chunk_size;
1690 break;
1691 }
1692
1693 case FOURCC('s', 'i', 'd', 'x'):
1694 {
1695 parseSegmentIndex(data_offset, chunk_data_size);
1696 *offset += chunk_size;
1697 return UNKNOWN_ERROR; // stop parsing after sidx
1698 }
1699
1700 default:
1701 {
1702 *offset += chunk_size;
1703 break;
1704 }
1705 }
1706
1707 return OK;
1708 }
1709
parseSegmentIndex(off64_t offset,size_t size)1710 status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
1711 ALOGV("MPEG4Extractor::parseSegmentIndex");
1712
1713 if (size < 12) {
1714 return -EINVAL;
1715 }
1716
1717 uint32_t flags;
1718 if (!mDataSource->getUInt32(offset, &flags)) {
1719 return ERROR_MALFORMED;
1720 }
1721
1722 uint32_t version = flags >> 24;
1723 flags &= 0xffffff;
1724
1725 ALOGV("sidx version %d", version);
1726
1727 uint32_t referenceId;
1728 if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
1729 return ERROR_MALFORMED;
1730 }
1731
1732 uint32_t timeScale;
1733 if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
1734 return ERROR_MALFORMED;
1735 }
1736 ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
1737
1738 uint64_t earliestPresentationTime;
1739 uint64_t firstOffset;
1740
1741 offset += 12;
1742 size -= 12;
1743
1744 if (version == 0) {
1745 if (size < 8) {
1746 return -EINVAL;
1747 }
1748 uint32_t tmp;
1749 if (!mDataSource->getUInt32(offset, &tmp)) {
1750 return ERROR_MALFORMED;
1751 }
1752 earliestPresentationTime = tmp;
1753 if (!mDataSource->getUInt32(offset + 4, &tmp)) {
1754 return ERROR_MALFORMED;
1755 }
1756 firstOffset = tmp;
1757 offset += 8;
1758 size -= 8;
1759 } else {
1760 if (size < 16) {
1761 return -EINVAL;
1762 }
1763 if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
1764 return ERROR_MALFORMED;
1765 }
1766 if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
1767 return ERROR_MALFORMED;
1768 }
1769 offset += 16;
1770 size -= 16;
1771 }
1772 ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset);
1773
1774 if (size < 4) {
1775 return -EINVAL;
1776 }
1777
1778 uint16_t referenceCount;
1779 if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
1780 return ERROR_MALFORMED;
1781 }
1782 offset += 4;
1783 size -= 4;
1784 ALOGV("refcount: %d", referenceCount);
1785
1786 if (size < referenceCount * 12) {
1787 return -EINVAL;
1788 }
1789
1790 uint64_t total_duration = 0;
1791 for (unsigned int i = 0; i < referenceCount; i++) {
1792 uint32_t d1, d2, d3;
1793
1794 if (!mDataSource->getUInt32(offset, &d1) || // size
1795 !mDataSource->getUInt32(offset + 4, &d2) || // duration
1796 !mDataSource->getUInt32(offset + 8, &d3)) { // flags
1797 return ERROR_MALFORMED;
1798 }
1799
1800 if (d1 & 0x80000000) {
1801 ALOGW("sub-sidx boxes not supported yet");
1802 }
1803 bool sap = d3 & 0x80000000;
1804 bool saptype = d3 >> 28;
1805 if (!sap || saptype > 2) {
1806 ALOGW("not a stream access point, or unsupported type");
1807 }
1808 total_duration += d2;
1809 offset += 12;
1810 ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
1811 SidxEntry se;
1812 se.mSize = d1 & 0x7fffffff;
1813 se.mDurationUs = 1000000LL * d2 / timeScale;
1814 mSidxEntries.add(se);
1815 }
1816
1817 mSidxDuration = total_duration * 1000000 / timeScale;
1818 ALOGV("duration: %lld", mSidxDuration);
1819
1820 int64_t metaDuration;
1821 if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
1822 mLastTrack->meta->setInt64(kKeyDuration, mSidxDuration);
1823 }
1824 return OK;
1825 }
1826
1827
1828
parseTrackHeader(off64_t data_offset,off64_t data_size)1829 status_t MPEG4Extractor::parseTrackHeader(
1830 off64_t data_offset, off64_t data_size) {
1831 if (data_size < 4) {
1832 return ERROR_MALFORMED;
1833 }
1834
1835 uint8_t version;
1836 if (mDataSource->readAt(data_offset, &version, 1) < 1) {
1837 return ERROR_IO;
1838 }
1839
1840 size_t dynSize = (version == 1) ? 36 : 24;
1841
1842 uint8_t buffer[36 + 60];
1843
1844 if (data_size != (off64_t)dynSize + 60) {
1845 return ERROR_MALFORMED;
1846 }
1847
1848 if (mDataSource->readAt(
1849 data_offset, buffer, data_size) < (ssize_t)data_size) {
1850 return ERROR_IO;
1851 }
1852
1853 uint64_t ctime, mtime, duration;
1854 int32_t id;
1855
1856 if (version == 1) {
1857 ctime = U64_AT(&buffer[4]);
1858 mtime = U64_AT(&buffer[12]);
1859 id = U32_AT(&buffer[20]);
1860 duration = U64_AT(&buffer[28]);
1861 } else {
1862 CHECK_EQ((unsigned)version, 0u);
1863
1864 ctime = U32_AT(&buffer[4]);
1865 mtime = U32_AT(&buffer[8]);
1866 id = U32_AT(&buffer[12]);
1867 duration = U32_AT(&buffer[20]);
1868 }
1869
1870 mLastTrack->meta->setInt32(kKeyTrackID, id);
1871
1872 size_t matrixOffset = dynSize + 16;
1873 int32_t a00 = U32_AT(&buffer[matrixOffset]);
1874 int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
1875 int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
1876 int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
1877 int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
1878 int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
1879
1880 #if 0
1881 ALOGI("x' = %.2f * x + %.2f * y + %.2f",
1882 a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
1883 ALOGI("y' = %.2f * x + %.2f * y + %.2f",
1884 a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
1885 #endif
1886
1887 uint32_t rotationDegrees;
1888
1889 static const int32_t kFixedOne = 0x10000;
1890 if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
1891 // Identity, no rotation
1892 rotationDegrees = 0;
1893 } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
1894 rotationDegrees = 90;
1895 } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
1896 rotationDegrees = 270;
1897 } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
1898 rotationDegrees = 180;
1899 } else {
1900 ALOGW("We only support 0,90,180,270 degree rotation matrices");
1901 rotationDegrees = 0;
1902 }
1903
1904 if (rotationDegrees != 0) {
1905 mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
1906 }
1907
1908 // Handle presentation display size, which could be different
1909 // from the image size indicated by kKeyWidth and kKeyHeight.
1910 uint32_t width = U32_AT(&buffer[dynSize + 52]);
1911 uint32_t height = U32_AT(&buffer[dynSize + 56]);
1912 mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
1913 mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
1914
1915 return OK;
1916 }
1917
parseMetaData(off64_t offset,size_t size)1918 status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) {
1919 if (size < 4) {
1920 return ERROR_MALFORMED;
1921 }
1922
1923 uint8_t *buffer = new uint8_t[size + 1];
1924 if (mDataSource->readAt(
1925 offset, buffer, size) != (ssize_t)size) {
1926 delete[] buffer;
1927 buffer = NULL;
1928
1929 return ERROR_IO;
1930 }
1931
1932 uint32_t flags = U32_AT(buffer);
1933
1934 uint32_t metadataKey = 0;
1935 char chunk[5];
1936 MakeFourCCString(mPath[4], chunk);
1937 ALOGV("meta: %s @ %lld", chunk, offset);
1938 switch (mPath[4]) {
1939 case FOURCC(0xa9, 'a', 'l', 'b'):
1940 {
1941 metadataKey = kKeyAlbum;
1942 break;
1943 }
1944 case FOURCC(0xa9, 'A', 'R', 'T'):
1945 {
1946 metadataKey = kKeyArtist;
1947 break;
1948 }
1949 case FOURCC('a', 'A', 'R', 'T'):
1950 {
1951 metadataKey = kKeyAlbumArtist;
1952 break;
1953 }
1954 case FOURCC(0xa9, 'd', 'a', 'y'):
1955 {
1956 metadataKey = kKeyYear;
1957 break;
1958 }
1959 case FOURCC(0xa9, 'n', 'a', 'm'):
1960 {
1961 metadataKey = kKeyTitle;
1962 break;
1963 }
1964 case FOURCC(0xa9, 'w', 'r', 't'):
1965 {
1966 metadataKey = kKeyWriter;
1967 break;
1968 }
1969 case FOURCC('c', 'o', 'v', 'r'):
1970 {
1971 metadataKey = kKeyAlbumArt;
1972 break;
1973 }
1974 case FOURCC('g', 'n', 'r', 'e'):
1975 {
1976 metadataKey = kKeyGenre;
1977 break;
1978 }
1979 case FOURCC(0xa9, 'g', 'e', 'n'):
1980 {
1981 metadataKey = kKeyGenre;
1982 break;
1983 }
1984 case FOURCC('c', 'p', 'i', 'l'):
1985 {
1986 if (size == 9 && flags == 21) {
1987 char tmp[16];
1988 sprintf(tmp, "%d",
1989 (int)buffer[size - 1]);
1990
1991 mFileMetaData->setCString(kKeyCompilation, tmp);
1992 }
1993 break;
1994 }
1995 case FOURCC('t', 'r', 'k', 'n'):
1996 {
1997 if (size == 16 && flags == 0) {
1998 char tmp[16];
1999 uint16_t* pTrack = (uint16_t*)&buffer[10];
2000 uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
2001 sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
2002
2003 mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
2004 }
2005 break;
2006 }
2007 case FOURCC('d', 'i', 's', 'k'):
2008 {
2009 if ((size == 14 || size == 16) && flags == 0) {
2010 char tmp[16];
2011 uint16_t* pDisc = (uint16_t*)&buffer[10];
2012 uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
2013 sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
2014
2015 mFileMetaData->setCString(kKeyDiscNumber, tmp);
2016 }
2017 break;
2018 }
2019 case FOURCC('-', '-', '-', '-'):
2020 {
2021 buffer[size] = '\0';
2022 switch (mPath[5]) {
2023 case FOURCC('m', 'e', 'a', 'n'):
2024 mLastCommentMean.setTo((const char *)buffer + 4);
2025 break;
2026 case FOURCC('n', 'a', 'm', 'e'):
2027 mLastCommentName.setTo((const char *)buffer + 4);
2028 break;
2029 case FOURCC('d', 'a', 't', 'a'):
2030 mLastCommentData.setTo((const char *)buffer + 8);
2031 break;
2032 }
2033
2034 // Once we have a set of mean/name/data info, go ahead and process
2035 // it to see if its something we are interested in. Whether or not
2036 // were are interested in the specific tag, make sure to clear out
2037 // the set so we can be ready to process another tuple should one
2038 // show up later in the file.
2039 if ((mLastCommentMean.length() != 0) &&
2040 (mLastCommentName.length() != 0) &&
2041 (mLastCommentData.length() != 0)) {
2042
2043 if (mLastCommentMean == "com.apple.iTunes"
2044 && mLastCommentName == "iTunSMPB") {
2045 int32_t delay, padding;
2046 if (sscanf(mLastCommentData,
2047 " %*x %x %x %*x", &delay, &padding) == 2) {
2048 mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
2049 mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
2050 }
2051 }
2052
2053 mLastCommentMean.clear();
2054 mLastCommentName.clear();
2055 mLastCommentData.clear();
2056 }
2057 break;
2058 }
2059
2060 default:
2061 break;
2062 }
2063
2064 if (size >= 8 && metadataKey) {
2065 if (metadataKey == kKeyAlbumArt) {
2066 mFileMetaData->setData(
2067 kKeyAlbumArt, MetaData::TYPE_NONE,
2068 buffer + 8, size - 8);
2069 } else if (metadataKey == kKeyGenre) {
2070 if (flags == 0) {
2071 // uint8_t genre code, iTunes genre codes are
2072 // the standard id3 codes, except they start
2073 // at 1 instead of 0 (e.g. Pop is 14, not 13)
2074 // We use standard id3 numbering, so subtract 1.
2075 int genrecode = (int)buffer[size - 1];
2076 genrecode--;
2077 if (genrecode < 0) {
2078 genrecode = 255; // reserved for 'unknown genre'
2079 }
2080 char genre[10];
2081 sprintf(genre, "%d", genrecode);
2082
2083 mFileMetaData->setCString(metadataKey, genre);
2084 } else if (flags == 1) {
2085 // custom genre string
2086 buffer[size] = '\0';
2087
2088 mFileMetaData->setCString(
2089 metadataKey, (const char *)buffer + 8);
2090 }
2091 } else {
2092 buffer[size] = '\0';
2093
2094 mFileMetaData->setCString(
2095 metadataKey, (const char *)buffer + 8);
2096 }
2097 }
2098
2099 delete[] buffer;
2100 buffer = NULL;
2101
2102 return OK;
2103 }
2104
getTrack(size_t index)2105 sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
2106 status_t err;
2107 if ((err = readMetaData()) != OK) {
2108 return NULL;
2109 }
2110
2111 Track *track = mFirstTrack;
2112 while (index > 0) {
2113 if (track == NULL) {
2114 return NULL;
2115 }
2116
2117 track = track->next;
2118 --index;
2119 }
2120
2121 if (track == NULL) {
2122 return NULL;
2123 }
2124
2125 ALOGV("getTrack called, pssh: %d", mPssh.size());
2126
2127 return new MPEG4Source(
2128 track->meta, mDataSource, track->timescale, track->sampleTable,
2129 mSidxEntries, mMoofOffset);
2130 }
2131
2132 // static
verifyTrack(Track * track)2133 status_t MPEG4Extractor::verifyTrack(Track *track) {
2134 const char *mime;
2135 CHECK(track->meta->findCString(kKeyMIMEType, &mime));
2136
2137 uint32_t type;
2138 const void *data;
2139 size_t size;
2140 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
2141 if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
2142 || type != kTypeAVCC) {
2143 return ERROR_MALFORMED;
2144 }
2145 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
2146 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2147 if (!track->meta->findData(kKeyESDS, &type, &data, &size)
2148 || type != kTypeESDS) {
2149 return ERROR_MALFORMED;
2150 }
2151 }
2152
2153 if (!track->sampleTable->isValid()) {
2154 // Make sure we have all the metadata we need.
2155 return ERROR_MALFORMED;
2156 }
2157
2158 return OK;
2159 }
2160
updateAudioTrackInfoFromESDS_MPEG4Audio(const void * esds_data,size_t esds_size)2161 status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
2162 const void *esds_data, size_t esds_size) {
2163 ESDS esds(esds_data, esds_size);
2164
2165 uint8_t objectTypeIndication;
2166 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
2167 return ERROR_MALFORMED;
2168 }
2169
2170 if (objectTypeIndication == 0xe1) {
2171 // This isn't MPEG4 audio at all, it's QCELP 14k...
2172 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
2173 return OK;
2174 }
2175
2176 if (objectTypeIndication == 0x6b) {
2177 // The media subtype is MP3 audio
2178 // Our software MP3 audio decoder may not be able to handle
2179 // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
2180 ALOGE("MP3 track in MP4/3GPP file is not supported");
2181 return ERROR_UNSUPPORTED;
2182 }
2183
2184 const uint8_t *csd;
2185 size_t csd_size;
2186 if (esds.getCodecSpecificInfo(
2187 (const void **)&csd, &csd_size) != OK) {
2188 return ERROR_MALFORMED;
2189 }
2190
2191 #if 0
2192 printf("ESD of size %d\n", csd_size);
2193 hexdump(csd, csd_size);
2194 #endif
2195
2196 if (csd_size == 0) {
2197 // There's no further information, i.e. no codec specific data
2198 // Let's assume that the information provided in the mpeg4 headers
2199 // is accurate and hope for the best.
2200
2201 return OK;
2202 }
2203
2204 if (csd_size < 2) {
2205 return ERROR_MALFORMED;
2206 }
2207
2208 ABitReader br(csd, csd_size);
2209 uint32_t objectType = br.getBits(5);
2210
2211 if (objectType == 31) { // AAC-ELD => additional 6 bits
2212 objectType = 32 + br.getBits(6);
2213 }
2214
2215 uint32_t freqIndex = br.getBits(4);
2216
2217 int32_t sampleRate = 0;
2218 int32_t numChannels = 0;
2219 if (freqIndex == 15) {
2220 if (csd_size < 5) {
2221 return ERROR_MALFORMED;
2222 }
2223 sampleRate = br.getBits(24);
2224 numChannels = br.getBits(4);
2225 } else {
2226 numChannels = br.getBits(4);
2227 if (objectType == 5) {
2228 // SBR specific config per 14496-3 table 1.13
2229 freqIndex = br.getBits(4);
2230 if (freqIndex == 15) {
2231 if (csd_size < 8) {
2232 return ERROR_MALFORMED;
2233 }
2234 sampleRate = br.getBits(24);
2235 }
2236 }
2237
2238 if (sampleRate == 0) {
2239 static uint32_t kSamplingRate[] = {
2240 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
2241 16000, 12000, 11025, 8000, 7350
2242 };
2243
2244 if (freqIndex == 13 || freqIndex == 14) {
2245 return ERROR_MALFORMED;
2246 }
2247
2248 sampleRate = kSamplingRate[freqIndex];
2249 }
2250 }
2251
2252 if (numChannels == 0) {
2253 return ERROR_UNSUPPORTED;
2254 }
2255
2256 int32_t prevSampleRate;
2257 CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
2258
2259 if (prevSampleRate != sampleRate) {
2260 ALOGV("mpeg4 audio sample rate different from previous setting. "
2261 "was: %d, now: %d", prevSampleRate, sampleRate);
2262 }
2263
2264 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
2265
2266 int32_t prevChannelCount;
2267 CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
2268
2269 if (prevChannelCount != numChannels) {
2270 ALOGV("mpeg4 audio channel count different from previous setting. "
2271 "was: %d, now: %d", prevChannelCount, numChannels);
2272 }
2273
2274 mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
2275
2276 return OK;
2277 }
2278
2279 ////////////////////////////////////////////////////////////////////////////////
2280
MPEG4Source(const sp<MetaData> & format,const sp<DataSource> & dataSource,int32_t timeScale,const sp<SampleTable> & sampleTable,Vector<SidxEntry> & sidx,off64_t firstMoofOffset)2281 MPEG4Source::MPEG4Source(
2282 const sp<MetaData> &format,
2283 const sp<DataSource> &dataSource,
2284 int32_t timeScale,
2285 const sp<SampleTable> &sampleTable,
2286 Vector<SidxEntry> &sidx,
2287 off64_t firstMoofOffset)
2288 : mFormat(format),
2289 mDataSource(dataSource),
2290 mTimescale(timeScale),
2291 mSampleTable(sampleTable),
2292 mCurrentSampleIndex(0),
2293 mCurrentFragmentIndex(0),
2294 mSegments(sidx),
2295 mFirstMoofOffset(firstMoofOffset),
2296 mCurrentMoofOffset(firstMoofOffset),
2297 mCurrentTime(0),
2298 mCurrentSampleInfoAllocSize(0),
2299 mCurrentSampleInfoSizes(NULL),
2300 mCurrentSampleInfoOffsetsAllocSize(0),
2301 mCurrentSampleInfoOffsets(NULL),
2302 mIsAVC(false),
2303 mNALLengthSize(0),
2304 mStarted(false),
2305 mGroup(NULL),
2306 mBuffer(NULL),
2307 mWantsNALFragments(false),
2308 mSrcBuffer(NULL) {
2309
2310 mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
2311 mDefaultIVSize = 0;
2312 mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
2313 uint32_t keytype;
2314 const void *key;
2315 size_t keysize;
2316 if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
2317 CHECK(keysize <= 16);
2318 memset(mCryptoKey, 0, 16);
2319 memcpy(mCryptoKey, key, keysize);
2320 }
2321
2322 const char *mime;
2323 bool success = mFormat->findCString(kKeyMIMEType, &mime);
2324 CHECK(success);
2325
2326 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
2327
2328 if (mIsAVC) {
2329 uint32_t type;
2330 const void *data;
2331 size_t size;
2332 CHECK(format->findData(kKeyAVCC, &type, &data, &size));
2333
2334 const uint8_t *ptr = (const uint8_t *)data;
2335
2336 CHECK(size >= 7);
2337 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
2338
2339 // The number of bytes used to encode the length of a NAL unit.
2340 mNALLengthSize = 1 + (ptr[4] & 3);
2341 }
2342
2343 CHECK(format->findInt32(kKeyTrackID, &mTrackId));
2344
2345 if (mFirstMoofOffset != 0) {
2346 off64_t offset = mFirstMoofOffset;
2347 parseChunk(&offset);
2348 }
2349 }
2350
~MPEG4Source()2351 MPEG4Source::~MPEG4Source() {
2352 if (mStarted) {
2353 stop();
2354 }
2355 free(mCurrentSampleInfoSizes);
2356 free(mCurrentSampleInfoOffsets);
2357 }
2358
start(MetaData * params)2359 status_t MPEG4Source::start(MetaData *params) {
2360 Mutex::Autolock autoLock(mLock);
2361
2362 CHECK(!mStarted);
2363
2364 int32_t val;
2365 if (params && params->findInt32(kKeyWantsNALFragments, &val)
2366 && val != 0) {
2367 mWantsNALFragments = true;
2368 } else {
2369 mWantsNALFragments = false;
2370 }
2371
2372 mGroup = new MediaBufferGroup;
2373
2374 int32_t max_size;
2375 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
2376
2377 mGroup->add_buffer(new MediaBuffer(max_size));
2378
2379 mSrcBuffer = new uint8_t[max_size];
2380
2381 mStarted = true;
2382
2383 return OK;
2384 }
2385
stop()2386 status_t MPEG4Source::stop() {
2387 Mutex::Autolock autoLock(mLock);
2388
2389 CHECK(mStarted);
2390
2391 if (mBuffer != NULL) {
2392 mBuffer->release();
2393 mBuffer = NULL;
2394 }
2395
2396 delete[] mSrcBuffer;
2397 mSrcBuffer = NULL;
2398
2399 delete mGroup;
2400 mGroup = NULL;
2401
2402 mStarted = false;
2403 mCurrentSampleIndex = 0;
2404
2405 return OK;
2406 }
2407
parseChunk(off64_t * offset)2408 status_t MPEG4Source::parseChunk(off64_t *offset) {
2409 uint32_t hdr[2];
2410 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
2411 return ERROR_IO;
2412 }
2413 uint64_t chunk_size = ntohl(hdr[0]);
2414 uint32_t chunk_type = ntohl(hdr[1]);
2415 off64_t data_offset = *offset + 8;
2416
2417 if (chunk_size == 1) {
2418 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
2419 return ERROR_IO;
2420 }
2421 chunk_size = ntoh64(chunk_size);
2422 data_offset += 8;
2423
2424 if (chunk_size < 16) {
2425 // The smallest valid chunk is 16 bytes long in this case.
2426 return ERROR_MALFORMED;
2427 }
2428 } else if (chunk_size < 8) {
2429 // The smallest valid chunk is 8 bytes long.
2430 return ERROR_MALFORMED;
2431 }
2432
2433 char chunk[5];
2434 MakeFourCCString(chunk_type, chunk);
2435 ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset);
2436
2437 off64_t chunk_data_size = *offset + chunk_size - data_offset;
2438
2439 switch(chunk_type) {
2440
2441 case FOURCC('t', 'r', 'a', 'f'):
2442 case FOURCC('m', 'o', 'o', 'f'): {
2443 off64_t stop_offset = *offset + chunk_size;
2444 *offset = data_offset;
2445 while (*offset < stop_offset) {
2446 status_t err = parseChunk(offset);
2447 if (err != OK) {
2448 return err;
2449 }
2450 }
2451 if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
2452 // *offset points to the mdat box following this moof
2453 parseChunk(offset); // doesn't actually parse it, just updates offset
2454 mNextMoofOffset = *offset;
2455 }
2456 break;
2457 }
2458
2459 case FOURCC('t', 'f', 'h', 'd'): {
2460 status_t err;
2461 if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
2462 return err;
2463 }
2464 *offset += chunk_size;
2465 break;
2466 }
2467
2468 case FOURCC('t', 'r', 'u', 'n'): {
2469 status_t err;
2470 if (mLastParsedTrackId == mTrackId) {
2471 if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
2472 return err;
2473 }
2474 }
2475
2476 *offset += chunk_size;
2477 break;
2478 }
2479
2480 case FOURCC('s', 'a', 'i', 'z'): {
2481 status_t err;
2482 if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
2483 return err;
2484 }
2485 *offset += chunk_size;
2486 break;
2487 }
2488 case FOURCC('s', 'a', 'i', 'o'): {
2489 status_t err;
2490 if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
2491 return err;
2492 }
2493 *offset += chunk_size;
2494 break;
2495 }
2496
2497 case FOURCC('m', 'd', 'a', 't'): {
2498 // parse DRM info if present
2499 ALOGV("MPEG4Source::parseChunk mdat");
2500 // if saiz/saoi was previously observed, do something with the sampleinfos
2501 *offset += chunk_size;
2502 break;
2503 }
2504
2505 default: {
2506 *offset += chunk_size;
2507 break;
2508 }
2509 }
2510 return OK;
2511 }
2512
parseSampleAuxiliaryInformationSizes(off64_t offset,off64_t size)2513 status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size) {
2514 ALOGV("parseSampleAuxiliaryInformationSizes");
2515 // 14496-12 8.7.12
2516 uint8_t version;
2517 if (mDataSource->readAt(
2518 offset, &version, sizeof(version))
2519 < (ssize_t)sizeof(version)) {
2520 return ERROR_IO;
2521 }
2522
2523 if (version != 0) {
2524 return ERROR_UNSUPPORTED;
2525 }
2526 offset++;
2527
2528 uint32_t flags;
2529 if (!mDataSource->getUInt24(offset, &flags)) {
2530 return ERROR_IO;
2531 }
2532 offset += 3;
2533
2534 if (flags & 1) {
2535 uint32_t tmp;
2536 if (!mDataSource->getUInt32(offset, &tmp)) {
2537 return ERROR_MALFORMED;
2538 }
2539 mCurrentAuxInfoType = tmp;
2540 offset += 4;
2541 if (!mDataSource->getUInt32(offset, &tmp)) {
2542 return ERROR_MALFORMED;
2543 }
2544 mCurrentAuxInfoTypeParameter = tmp;
2545 offset += 4;
2546 }
2547
2548 uint8_t defsize;
2549 if (mDataSource->readAt(offset, &defsize, 1) != 1) {
2550 return ERROR_MALFORMED;
2551 }
2552 mCurrentDefaultSampleInfoSize = defsize;
2553 offset++;
2554
2555 uint32_t smplcnt;
2556 if (!mDataSource->getUInt32(offset, &smplcnt)) {
2557 return ERROR_MALFORMED;
2558 }
2559 mCurrentSampleInfoCount = smplcnt;
2560 offset += 4;
2561
2562 if (mCurrentDefaultSampleInfoSize != 0) {
2563 ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
2564 return OK;
2565 }
2566 if (smplcnt > mCurrentSampleInfoAllocSize) {
2567 mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
2568 mCurrentSampleInfoAllocSize = smplcnt;
2569 }
2570
2571 mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
2572 return OK;
2573 }
2574
parseSampleAuxiliaryInformationOffsets(off64_t offset,off64_t size)2575 status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size) {
2576 ALOGV("parseSampleAuxiliaryInformationOffsets");
2577 // 14496-12 8.7.13
2578 uint8_t version;
2579 if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
2580 return ERROR_IO;
2581 }
2582 offset++;
2583
2584 uint32_t flags;
2585 if (!mDataSource->getUInt24(offset, &flags)) {
2586 return ERROR_IO;
2587 }
2588 offset += 3;
2589
2590 uint32_t entrycount;
2591 if (!mDataSource->getUInt32(offset, &entrycount)) {
2592 return ERROR_IO;
2593 }
2594 offset += 4;
2595
2596 if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
2597 mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8);
2598 mCurrentSampleInfoOffsetsAllocSize = entrycount;
2599 }
2600 mCurrentSampleInfoOffsetCount = entrycount;
2601
2602 for (size_t i = 0; i < entrycount; i++) {
2603 if (version == 0) {
2604 uint32_t tmp;
2605 if (!mDataSource->getUInt32(offset, &tmp)) {
2606 return ERROR_IO;
2607 }
2608 mCurrentSampleInfoOffsets[i] = tmp;
2609 offset += 4;
2610 } else {
2611 uint64_t tmp;
2612 if (!mDataSource->getUInt64(offset, &tmp)) {
2613 return ERROR_IO;
2614 }
2615 mCurrentSampleInfoOffsets[i] = tmp;
2616 offset += 8;
2617 }
2618 }
2619
2620 // parse clear/encrypted data
2621
2622 off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
2623
2624 drmoffset += mCurrentMoofOffset;
2625 int ivlength;
2626 CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
2627
2628 // read CencSampleAuxiliaryDataFormats
2629 for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
2630 Sample *smpl = &mCurrentSamples.editItemAt(i);
2631
2632 memset(smpl->iv, 0, 16);
2633 if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) {
2634 return ERROR_IO;
2635 }
2636
2637 drmoffset += ivlength;
2638
2639 int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
2640 if (smplinfosize == 0) {
2641 smplinfosize = mCurrentSampleInfoSizes[i];
2642 }
2643 if (smplinfosize > ivlength) {
2644 uint16_t numsubsamples;
2645 if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
2646 return ERROR_IO;
2647 }
2648 drmoffset += 2;
2649 for (size_t j = 0; j < numsubsamples; j++) {
2650 uint16_t numclear;
2651 uint32_t numencrypted;
2652 if (!mDataSource->getUInt16(drmoffset, &numclear)) {
2653 return ERROR_IO;
2654 }
2655 drmoffset += 2;
2656 if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
2657 return ERROR_IO;
2658 }
2659 drmoffset += 4;
2660 smpl->clearsizes.add(numclear);
2661 smpl->encryptedsizes.add(numencrypted);
2662 }
2663 } else {
2664 smpl->clearsizes.add(0);
2665 smpl->encryptedsizes.add(smpl->size);
2666 }
2667 }
2668
2669
2670 return OK;
2671 }
2672
parseTrackFragmentHeader(off64_t offset,off64_t size)2673 status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
2674
2675 if (size < 8) {
2676 return -EINVAL;
2677 }
2678
2679 uint32_t flags;
2680 if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
2681 return ERROR_MALFORMED;
2682 }
2683
2684 if (flags & 0xff000000) {
2685 return -EINVAL;
2686 }
2687
2688 if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
2689 return ERROR_MALFORMED;
2690 }
2691
2692 if (mLastParsedTrackId != mTrackId) {
2693 // this is not the right track, skip it
2694 return OK;
2695 }
2696
2697 mTrackFragmentHeaderInfo.mFlags = flags;
2698 mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
2699 offset += 8;
2700 size -= 8;
2701
2702 ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
2703
2704 if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
2705 if (size < 8) {
2706 return -EINVAL;
2707 }
2708
2709 if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
2710 return ERROR_MALFORMED;
2711 }
2712 offset += 8;
2713 size -= 8;
2714 }
2715
2716 if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
2717 if (size < 4) {
2718 return -EINVAL;
2719 }
2720
2721 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
2722 return ERROR_MALFORMED;
2723 }
2724 offset += 4;
2725 size -= 4;
2726 }
2727
2728 if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
2729 if (size < 4) {
2730 return -EINVAL;
2731 }
2732
2733 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
2734 return ERROR_MALFORMED;
2735 }
2736 offset += 4;
2737 size -= 4;
2738 }
2739
2740 if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
2741 if (size < 4) {
2742 return -EINVAL;
2743 }
2744
2745 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
2746 return ERROR_MALFORMED;
2747 }
2748 offset += 4;
2749 size -= 4;
2750 }
2751
2752 if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
2753 if (size < 4) {
2754 return -EINVAL;
2755 }
2756
2757 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
2758 return ERROR_MALFORMED;
2759 }
2760 offset += 4;
2761 size -= 4;
2762 }
2763
2764 if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
2765 mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
2766 }
2767
2768 mTrackFragmentHeaderInfo.mDataOffset = 0;
2769 return OK;
2770 }
2771
parseTrackFragmentRun(off64_t offset,off64_t size)2772 status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
2773
2774 ALOGV("MPEG4Extractor::parseTrackFragmentRun");
2775 if (size < 8) {
2776 return -EINVAL;
2777 }
2778
2779 enum {
2780 kDataOffsetPresent = 0x01,
2781 kFirstSampleFlagsPresent = 0x04,
2782 kSampleDurationPresent = 0x100,
2783 kSampleSizePresent = 0x200,
2784 kSampleFlagsPresent = 0x400,
2785 kSampleCompositionTimeOffsetPresent = 0x800,
2786 };
2787
2788 uint32_t flags;
2789 if (!mDataSource->getUInt32(offset, &flags)) {
2790 return ERROR_MALFORMED;
2791 }
2792 ALOGV("fragment run flags: %08x", flags);
2793
2794 if (flags & 0xff000000) {
2795 return -EINVAL;
2796 }
2797
2798 if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
2799 // These two shall not be used together.
2800 return -EINVAL;
2801 }
2802
2803 uint32_t sampleCount;
2804 if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
2805 return ERROR_MALFORMED;
2806 }
2807 offset += 8;
2808 size -= 8;
2809
2810 uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
2811
2812 uint32_t firstSampleFlags = 0;
2813
2814 if (flags & kDataOffsetPresent) {
2815 if (size < 4) {
2816 return -EINVAL;
2817 }
2818
2819 int32_t dataOffsetDelta;
2820 if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) {
2821 return ERROR_MALFORMED;
2822 }
2823
2824 dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
2825
2826 offset += 4;
2827 size -= 4;
2828 }
2829
2830 if (flags & kFirstSampleFlagsPresent) {
2831 if (size < 4) {
2832 return -EINVAL;
2833 }
2834
2835 if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
2836 return ERROR_MALFORMED;
2837 }
2838 offset += 4;
2839 size -= 4;
2840 }
2841
2842 uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
2843 sampleCtsOffset = 0;
2844
2845 size_t bytesPerSample = 0;
2846 if (flags & kSampleDurationPresent) {
2847 bytesPerSample += 4;
2848 } else if (mTrackFragmentHeaderInfo.mFlags
2849 & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
2850 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
2851 } else {
2852 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
2853 }
2854
2855 if (flags & kSampleSizePresent) {
2856 bytesPerSample += 4;
2857 } else if (mTrackFragmentHeaderInfo.mFlags
2858 & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
2859 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
2860 } else {
2861 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
2862 }
2863
2864 if (flags & kSampleFlagsPresent) {
2865 bytesPerSample += 4;
2866 } else if (mTrackFragmentHeaderInfo.mFlags
2867 & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
2868 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
2869 } else {
2870 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
2871 }
2872
2873 if (flags & kSampleCompositionTimeOffsetPresent) {
2874 bytesPerSample += 4;
2875 } else {
2876 sampleCtsOffset = 0;
2877 }
2878
2879 if (size < sampleCount * bytesPerSample) {
2880 return -EINVAL;
2881 }
2882
2883 Sample tmp;
2884 for (uint32_t i = 0; i < sampleCount; ++i) {
2885 if (flags & kSampleDurationPresent) {
2886 if (!mDataSource->getUInt32(offset, &sampleDuration)) {
2887 return ERROR_MALFORMED;
2888 }
2889 offset += 4;
2890 }
2891
2892 if (flags & kSampleSizePresent) {
2893 if (!mDataSource->getUInt32(offset, &sampleSize)) {
2894 return ERROR_MALFORMED;
2895 }
2896 offset += 4;
2897 }
2898
2899 if (flags & kSampleFlagsPresent) {
2900 if (!mDataSource->getUInt32(offset, &sampleFlags)) {
2901 return ERROR_MALFORMED;
2902 }
2903 offset += 4;
2904 }
2905
2906 if (flags & kSampleCompositionTimeOffsetPresent) {
2907 if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
2908 return ERROR_MALFORMED;
2909 }
2910 offset += 4;
2911 }
2912
2913 ALOGV("adding sample %d at offset 0x%08llx, size %u, duration %u, "
2914 " flags 0x%08x", i + 1,
2915 dataOffset, sampleSize, sampleDuration,
2916 (flags & kFirstSampleFlagsPresent) && i == 0
2917 ? firstSampleFlags : sampleFlags);
2918 tmp.offset = dataOffset;
2919 tmp.size = sampleSize;
2920 tmp.duration = sampleDuration;
2921 mCurrentSamples.add(tmp);
2922
2923 dataOffset += sampleSize;
2924 }
2925
2926 mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
2927
2928 return OK;
2929 }
2930
getFormat()2931 sp<MetaData> MPEG4Source::getFormat() {
2932 Mutex::Autolock autoLock(mLock);
2933
2934 return mFormat;
2935 }
2936
parseNALSize(const uint8_t * data) const2937 size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
2938 switch (mNALLengthSize) {
2939 case 1:
2940 return *data;
2941 case 2:
2942 return U16_AT(data);
2943 case 3:
2944 return ((size_t)data[0] << 16) | U16_AT(&data[1]);
2945 case 4:
2946 return U32_AT(data);
2947 }
2948
2949 // This cannot happen, mNALLengthSize springs to life by adding 1 to
2950 // a 2-bit integer.
2951 CHECK(!"Should not be here.");
2952
2953 return 0;
2954 }
2955
read(MediaBuffer ** out,const ReadOptions * options)2956 status_t MPEG4Source::read(
2957 MediaBuffer **out, const ReadOptions *options) {
2958 Mutex::Autolock autoLock(mLock);
2959
2960 CHECK(mStarted);
2961
2962 if (mFirstMoofOffset > 0) {
2963 return fragmentedRead(out, options);
2964 }
2965
2966 *out = NULL;
2967
2968 int64_t targetSampleTimeUs = -1;
2969
2970 int64_t seekTimeUs;
2971 ReadOptions::SeekMode mode;
2972 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
2973 uint32_t findFlags = 0;
2974 switch (mode) {
2975 case ReadOptions::SEEK_PREVIOUS_SYNC:
2976 findFlags = SampleTable::kFlagBefore;
2977 break;
2978 case ReadOptions::SEEK_NEXT_SYNC:
2979 findFlags = SampleTable::kFlagAfter;
2980 break;
2981 case ReadOptions::SEEK_CLOSEST_SYNC:
2982 case ReadOptions::SEEK_CLOSEST:
2983 findFlags = SampleTable::kFlagClosest;
2984 break;
2985 default:
2986 CHECK(!"Should not be here.");
2987 break;
2988 }
2989
2990 uint32_t sampleIndex;
2991 status_t err = mSampleTable->findSampleAtTime(
2992 seekTimeUs * mTimescale / 1000000,
2993 &sampleIndex, findFlags);
2994
2995 if (mode == ReadOptions::SEEK_CLOSEST) {
2996 // We found the closest sample already, now we want the sync
2997 // sample preceding it (or the sample itself of course), even
2998 // if the subsequent sync sample is closer.
2999 findFlags = SampleTable::kFlagBefore;
3000 }
3001
3002 uint32_t syncSampleIndex;
3003 if (err == OK) {
3004 err = mSampleTable->findSyncSampleNear(
3005 sampleIndex, &syncSampleIndex, findFlags);
3006 }
3007
3008 uint32_t sampleTime;
3009 if (err == OK) {
3010 err = mSampleTable->getMetaDataForSample(
3011 sampleIndex, NULL, NULL, &sampleTime);
3012 }
3013
3014 if (err != OK) {
3015 if (err == ERROR_OUT_OF_RANGE) {
3016 // An attempt to seek past the end of the stream would
3017 // normally cause this ERROR_OUT_OF_RANGE error. Propagating
3018 // this all the way to the MediaPlayer would cause abnormal
3019 // termination. Legacy behaviour appears to be to behave as if
3020 // we had seeked to the end of stream, ending normally.
3021 err = ERROR_END_OF_STREAM;
3022 }
3023 ALOGV("end of stream");
3024 return err;
3025 }
3026
3027 if (mode == ReadOptions::SEEK_CLOSEST) {
3028 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
3029 }
3030
3031 #if 0
3032 uint32_t syncSampleTime;
3033 CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
3034 syncSampleIndex, NULL, NULL, &syncSampleTime));
3035
3036 ALOGI("seek to time %lld us => sample at time %lld us, "
3037 "sync sample at time %lld us",
3038 seekTimeUs,
3039 sampleTime * 1000000ll / mTimescale,
3040 syncSampleTime * 1000000ll / mTimescale);
3041 #endif
3042
3043 mCurrentSampleIndex = syncSampleIndex;
3044 if (mBuffer != NULL) {
3045 mBuffer->release();
3046 mBuffer = NULL;
3047 }
3048
3049 // fall through
3050 }
3051
3052 off64_t offset;
3053 size_t size;
3054 uint32_t cts;
3055 bool isSyncSample;
3056 bool newBuffer = false;
3057 if (mBuffer == NULL) {
3058 newBuffer = true;
3059
3060 status_t err =
3061 mSampleTable->getMetaDataForSample(
3062 mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);
3063
3064 if (err != OK) {
3065 return err;
3066 }
3067
3068 err = mGroup->acquire_buffer(&mBuffer);
3069
3070 if (err != OK) {
3071 CHECK(mBuffer == NULL);
3072 return err;
3073 }
3074 }
3075
3076 if (!mIsAVC || mWantsNALFragments) {
3077 if (newBuffer) {
3078 ssize_t num_bytes_read =
3079 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
3080
3081 if (num_bytes_read < (ssize_t)size) {
3082 mBuffer->release();
3083 mBuffer = NULL;
3084
3085 return ERROR_IO;
3086 }
3087
3088 CHECK(mBuffer != NULL);
3089 mBuffer->set_range(0, size);
3090 mBuffer->meta_data()->clear();
3091 mBuffer->meta_data()->setInt64(
3092 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
3093
3094 if (targetSampleTimeUs >= 0) {
3095 mBuffer->meta_data()->setInt64(
3096 kKeyTargetTime, targetSampleTimeUs);
3097 }
3098
3099 if (isSyncSample) {
3100 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
3101 }
3102
3103 ++mCurrentSampleIndex;
3104 }
3105
3106 if (!mIsAVC) {
3107 *out = mBuffer;
3108 mBuffer = NULL;
3109
3110 return OK;
3111 }
3112
3113 // Each NAL unit is split up into its constituent fragments and
3114 // each one of them returned in its own buffer.
3115
3116 CHECK(mBuffer->range_length() >= mNALLengthSize);
3117
3118 const uint8_t *src =
3119 (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
3120
3121 size_t nal_size = parseNALSize(src);
3122 if (mBuffer->range_length() < mNALLengthSize + nal_size) {
3123 ALOGE("incomplete NAL unit.");
3124
3125 mBuffer->release();
3126 mBuffer = NULL;
3127
3128 return ERROR_MALFORMED;
3129 }
3130
3131 MediaBuffer *clone = mBuffer->clone();
3132 CHECK(clone != NULL);
3133 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
3134
3135 CHECK(mBuffer != NULL);
3136 mBuffer->set_range(
3137 mBuffer->range_offset() + mNALLengthSize + nal_size,
3138 mBuffer->range_length() - mNALLengthSize - nal_size);
3139
3140 if (mBuffer->range_length() == 0) {
3141 mBuffer->release();
3142 mBuffer = NULL;
3143 }
3144
3145 *out = clone;
3146
3147 return OK;
3148 } else {
3149 // Whole NAL units are returned but each fragment is prefixed by
3150 // the start code (0x00 00 00 01).
3151 ssize_t num_bytes_read = 0;
3152 int32_t drm = 0;
3153 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
3154 if (usesDRM) {
3155 num_bytes_read =
3156 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
3157 } else {
3158 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
3159 }
3160
3161 if (num_bytes_read < (ssize_t)size) {
3162 mBuffer->release();
3163 mBuffer = NULL;
3164
3165 return ERROR_IO;
3166 }
3167
3168 if (usesDRM) {
3169 CHECK(mBuffer != NULL);
3170 mBuffer->set_range(0, size);
3171
3172 } else {
3173 uint8_t *dstData = (uint8_t *)mBuffer->data();
3174 size_t srcOffset = 0;
3175 size_t dstOffset = 0;
3176
3177 while (srcOffset < size) {
3178 bool isMalFormed = (srcOffset + mNALLengthSize > size);
3179 size_t nalLength = 0;
3180 if (!isMalFormed) {
3181 nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
3182 srcOffset += mNALLengthSize;
3183 isMalFormed = srcOffset + nalLength > size;
3184 }
3185
3186 if (isMalFormed) {
3187 ALOGE("Video is malformed");
3188 mBuffer->release();
3189 mBuffer = NULL;
3190 return ERROR_MALFORMED;
3191 }
3192
3193 if (nalLength == 0) {
3194 continue;
3195 }
3196
3197 CHECK(dstOffset + 4 <= mBuffer->size());
3198
3199 dstData[dstOffset++] = 0;
3200 dstData[dstOffset++] = 0;
3201 dstData[dstOffset++] = 0;
3202 dstData[dstOffset++] = 1;
3203 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
3204 srcOffset += nalLength;
3205 dstOffset += nalLength;
3206 }
3207 CHECK_EQ(srcOffset, size);
3208 CHECK(mBuffer != NULL);
3209 mBuffer->set_range(0, dstOffset);
3210 }
3211
3212 mBuffer->meta_data()->clear();
3213 mBuffer->meta_data()->setInt64(
3214 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
3215
3216 if (targetSampleTimeUs >= 0) {
3217 mBuffer->meta_data()->setInt64(
3218 kKeyTargetTime, targetSampleTimeUs);
3219 }
3220
3221 if (isSyncSample) {
3222 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
3223 }
3224
3225 ++mCurrentSampleIndex;
3226
3227 *out = mBuffer;
3228 mBuffer = NULL;
3229
3230 return OK;
3231 }
3232 }
3233
fragmentedRead(MediaBuffer ** out,const ReadOptions * options)3234 status_t MPEG4Source::fragmentedRead(
3235 MediaBuffer **out, const ReadOptions *options) {
3236
3237 ALOGV("MPEG4Source::fragmentedRead");
3238
3239 CHECK(mStarted);
3240
3241 *out = NULL;
3242
3243 int64_t targetSampleTimeUs = -1;
3244
3245 int64_t seekTimeUs;
3246 ReadOptions::SeekMode mode;
3247 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
3248
3249 int numSidxEntries = mSegments.size();
3250 if (numSidxEntries != 0) {
3251 int64_t totalTime = 0;
3252 off64_t totalOffset = mFirstMoofOffset;
3253 for (int i = 0; i < numSidxEntries; i++) {
3254 const SidxEntry *se = &mSegments[i];
3255 if (totalTime + se->mDurationUs > seekTimeUs) {
3256 // The requested time is somewhere in this segment
3257 if ((mode == ReadOptions::SEEK_NEXT_SYNC) ||
3258 (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
3259 (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
3260 // requested next sync, or closest sync and it was closer to the end of
3261 // this segment
3262 totalTime += se->mDurationUs;
3263 totalOffset += se->mSize;
3264 }
3265 break;
3266 }
3267 totalTime += se->mDurationUs;
3268 totalOffset += se->mSize;
3269 }
3270 mCurrentMoofOffset = totalOffset;
3271 mCurrentSamples.clear();
3272 mCurrentSampleIndex = 0;
3273 parseChunk(&totalOffset);
3274 mCurrentTime = totalTime * mTimescale / 1000000ll;
3275 }
3276
3277 if (mBuffer != NULL) {
3278 mBuffer->release();
3279 mBuffer = NULL;
3280 }
3281
3282 // fall through
3283 }
3284
3285 off64_t offset = 0;
3286 size_t size;
3287 uint32_t cts = 0;
3288 bool isSyncSample = false;
3289 bool newBuffer = false;
3290 if (mBuffer == NULL) {
3291 newBuffer = true;
3292
3293 if (mCurrentSampleIndex >= mCurrentSamples.size()) {
3294 // move to next fragment
3295 Sample lastSample = mCurrentSamples[mCurrentSamples.size() - 1];
3296 off64_t nextMoof = mNextMoofOffset; // lastSample.offset + lastSample.size;
3297 mCurrentMoofOffset = nextMoof;
3298 mCurrentSamples.clear();
3299 mCurrentSampleIndex = 0;
3300 parseChunk(&nextMoof);
3301 if (mCurrentSampleIndex >= mCurrentSamples.size()) {
3302 return ERROR_END_OF_STREAM;
3303 }
3304 }
3305
3306 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
3307 offset = smpl->offset;
3308 size = smpl->size;
3309 cts = mCurrentTime;
3310 mCurrentTime += smpl->duration;
3311 isSyncSample = (mCurrentSampleIndex == 0); // XXX
3312
3313 status_t err = mGroup->acquire_buffer(&mBuffer);
3314
3315 if (err != OK) {
3316 CHECK(mBuffer == NULL);
3317 ALOGV("acquire_buffer returned %d", err);
3318 return err;
3319 }
3320 }
3321
3322 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
3323 const sp<MetaData> bufmeta = mBuffer->meta_data();
3324 bufmeta->clear();
3325 if (smpl->encryptedsizes.size()) {
3326 // store clear/encrypted lengths in metadata
3327 bufmeta->setData(kKeyPlainSizes, 0,
3328 smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
3329 bufmeta->setData(kKeyEncryptedSizes, 0,
3330 smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
3331 bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
3332 bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
3333 bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
3334 bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
3335 }
3336
3337 if (!mIsAVC || mWantsNALFragments) {
3338 if (newBuffer) {
3339 ssize_t num_bytes_read =
3340 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
3341
3342 if (num_bytes_read < (ssize_t)size) {
3343 mBuffer->release();
3344 mBuffer = NULL;
3345
3346 ALOGV("i/o error");
3347 return ERROR_IO;
3348 }
3349
3350 CHECK(mBuffer != NULL);
3351 mBuffer->set_range(0, size);
3352 mBuffer->meta_data()->setInt64(
3353 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
3354
3355 if (targetSampleTimeUs >= 0) {
3356 mBuffer->meta_data()->setInt64(
3357 kKeyTargetTime, targetSampleTimeUs);
3358 }
3359
3360 if (isSyncSample) {
3361 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
3362 }
3363
3364 ++mCurrentSampleIndex;
3365 }
3366
3367 if (!mIsAVC) {
3368 *out = mBuffer;
3369 mBuffer = NULL;
3370
3371 return OK;
3372 }
3373
3374 // Each NAL unit is split up into its constituent fragments and
3375 // each one of them returned in its own buffer.
3376
3377 CHECK(mBuffer->range_length() >= mNALLengthSize);
3378
3379 const uint8_t *src =
3380 (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
3381
3382 size_t nal_size = parseNALSize(src);
3383 if (mBuffer->range_length() < mNALLengthSize + nal_size) {
3384 ALOGE("incomplete NAL unit.");
3385
3386 mBuffer->release();
3387 mBuffer = NULL;
3388
3389 return ERROR_MALFORMED;
3390 }
3391
3392 MediaBuffer *clone = mBuffer->clone();
3393 CHECK(clone != NULL);
3394 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
3395
3396 CHECK(mBuffer != NULL);
3397 mBuffer->set_range(
3398 mBuffer->range_offset() + mNALLengthSize + nal_size,
3399 mBuffer->range_length() - mNALLengthSize - nal_size);
3400
3401 if (mBuffer->range_length() == 0) {
3402 mBuffer->release();
3403 mBuffer = NULL;
3404 }
3405
3406 *out = clone;
3407
3408 return OK;
3409 } else {
3410 ALOGV("whole NAL");
3411 // Whole NAL units are returned but each fragment is prefixed by
3412 // the start code (0x00 00 00 01).
3413 ssize_t num_bytes_read = 0;
3414 int32_t drm = 0;
3415 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
3416 if (usesDRM) {
3417 num_bytes_read =
3418 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
3419 } else {
3420 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
3421 }
3422
3423 if (num_bytes_read < (ssize_t)size) {
3424 mBuffer->release();
3425 mBuffer = NULL;
3426
3427 ALOGV("i/o error");
3428 return ERROR_IO;
3429 }
3430
3431 if (usesDRM) {
3432 CHECK(mBuffer != NULL);
3433 mBuffer->set_range(0, size);
3434
3435 } else {
3436 uint8_t *dstData = (uint8_t *)mBuffer->data();
3437 size_t srcOffset = 0;
3438 size_t dstOffset = 0;
3439
3440 while (srcOffset < size) {
3441 bool isMalFormed = (srcOffset + mNALLengthSize > size);
3442 size_t nalLength = 0;
3443 if (!isMalFormed) {
3444 nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
3445 srcOffset += mNALLengthSize;
3446 isMalFormed = srcOffset + nalLength > size;
3447 }
3448
3449 if (isMalFormed) {
3450 ALOGE("Video is malformed");
3451 mBuffer->release();
3452 mBuffer = NULL;
3453 return ERROR_MALFORMED;
3454 }
3455
3456 if (nalLength == 0) {
3457 continue;
3458 }
3459
3460 CHECK(dstOffset + 4 <= mBuffer->size());
3461
3462 dstData[dstOffset++] = 0;
3463 dstData[dstOffset++] = 0;
3464 dstData[dstOffset++] = 0;
3465 dstData[dstOffset++] = 1;
3466 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
3467 srcOffset += nalLength;
3468 dstOffset += nalLength;
3469 }
3470 CHECK_EQ(srcOffset, size);
3471 CHECK(mBuffer != NULL);
3472 mBuffer->set_range(0, dstOffset);
3473 }
3474
3475 mBuffer->meta_data()->setInt64(
3476 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
3477
3478 if (targetSampleTimeUs >= 0) {
3479 mBuffer->meta_data()->setInt64(
3480 kKeyTargetTime, targetSampleTimeUs);
3481 }
3482
3483 if (isSyncSample) {
3484 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
3485 }
3486
3487 ++mCurrentSampleIndex;
3488
3489 *out = mBuffer;
3490 mBuffer = NULL;
3491
3492 return OK;
3493 }
3494 }
3495
findTrackByMimePrefix(const char * mimePrefix)3496 MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
3497 const char *mimePrefix) {
3498 for (Track *track = mFirstTrack; track != NULL; track = track->next) {
3499 const char *mime;
3500 if (track->meta != NULL
3501 && track->meta->findCString(kKeyMIMEType, &mime)
3502 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
3503 return track;
3504 }
3505 }
3506
3507 return NULL;
3508 }
3509
LegacySniffMPEG4(const sp<DataSource> & source,String8 * mimeType,float * confidence)3510 static bool LegacySniffMPEG4(
3511 const sp<DataSource> &source, String8 *mimeType, float *confidence) {
3512 uint8_t header[8];
3513
3514 ssize_t n = source->readAt(4, header, sizeof(header));
3515 if (n < (ssize_t)sizeof(header)) {
3516 return false;
3517 }
3518
3519 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
3520 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
3521 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
3522 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
3523 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
3524 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
3525 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
3526 *confidence = 0.4;
3527
3528 return true;
3529 }
3530
3531 return false;
3532 }
3533
isCompatibleBrand(uint32_t fourcc)3534 static bool isCompatibleBrand(uint32_t fourcc) {
3535 static const uint32_t kCompatibleBrands[] = {
3536 FOURCC('i', 's', 'o', 'm'),
3537 FOURCC('i', 's', 'o', '2'),
3538 FOURCC('a', 'v', 'c', '1'),
3539 FOURCC('3', 'g', 'p', '4'),
3540 FOURCC('m', 'p', '4', '1'),
3541 FOURCC('m', 'p', '4', '2'),
3542
3543 // Won't promise that the following file types can be played.
3544 // Just give these file types a chance.
3545 FOURCC('q', 't', ' ', ' '), // Apple's QuickTime
3546 FOURCC('M', 'S', 'N', 'V'), // Sony's PSP
3547
3548 FOURCC('3', 'g', '2', 'a'), // 3GPP2
3549 FOURCC('3', 'g', '2', 'b'),
3550 };
3551
3552 for (size_t i = 0;
3553 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
3554 ++i) {
3555 if (kCompatibleBrands[i] == fourcc) {
3556 return true;
3557 }
3558 }
3559
3560 return false;
3561 }
3562
3563 // Attempt to actually parse the 'ftyp' atom and determine if a suitable
3564 // compatible brand is present.
3565 // Also try to identify where this file's metadata ends
3566 // (end of the 'moov' atom) and report it to the caller as part of
3567 // the metadata.
BetterSniffMPEG4(const sp<DataSource> & source,String8 * mimeType,float * confidence,sp<AMessage> * meta)3568 static bool BetterSniffMPEG4(
3569 const sp<DataSource> &source, String8 *mimeType, float *confidence,
3570 sp<AMessage> *meta) {
3571 // We scan up to 128 bytes to identify this file as an MP4.
3572 static const off64_t kMaxScanOffset = 128ll;
3573
3574 off64_t offset = 0ll;
3575 bool foundGoodFileType = false;
3576 off64_t moovAtomEndOffset = -1ll;
3577 bool done = false;
3578
3579 while (!done && offset < kMaxScanOffset) {
3580 uint32_t hdr[2];
3581 if (source->readAt(offset, hdr, 8) < 8) {
3582 return false;
3583 }
3584
3585 uint64_t chunkSize = ntohl(hdr[0]);
3586 uint32_t chunkType = ntohl(hdr[1]);
3587 off64_t chunkDataOffset = offset + 8;
3588
3589 if (chunkSize == 1) {
3590 if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
3591 return false;
3592 }
3593
3594 chunkSize = ntoh64(chunkSize);
3595 chunkDataOffset += 8;
3596
3597 if (chunkSize < 16) {
3598 // The smallest valid chunk is 16 bytes long in this case.
3599 return false;
3600 }
3601 } else if (chunkSize < 8) {
3602 // The smallest valid chunk is 8 bytes long.
3603 return false;
3604 }
3605
3606 off64_t chunkDataSize = offset + chunkSize - chunkDataOffset;
3607
3608 char chunkstring[5];
3609 MakeFourCCString(chunkType, chunkstring);
3610 ALOGV("saw chunk type %s, size %lld @ %lld", chunkstring, chunkSize, offset);
3611 switch (chunkType) {
3612 case FOURCC('f', 't', 'y', 'p'):
3613 {
3614 if (chunkDataSize < 8) {
3615 return false;
3616 }
3617
3618 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
3619 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
3620 if (i == 1) {
3621 // Skip this index, it refers to the minorVersion,
3622 // not a brand.
3623 continue;
3624 }
3625
3626 uint32_t brand;
3627 if (source->readAt(
3628 chunkDataOffset + 4 * i, &brand, 4) < 4) {
3629 return false;
3630 }
3631
3632 brand = ntohl(brand);
3633
3634 if (isCompatibleBrand(brand)) {
3635 foundGoodFileType = true;
3636 break;
3637 }
3638 }
3639
3640 if (!foundGoodFileType) {
3641 return false;
3642 }
3643
3644 break;
3645 }
3646
3647 case FOURCC('m', 'o', 'o', 'v'):
3648 {
3649 moovAtomEndOffset = offset + chunkSize;
3650
3651 done = true;
3652 break;
3653 }
3654
3655 default:
3656 break;
3657 }
3658
3659 offset += chunkSize;
3660 }
3661
3662 if (!foundGoodFileType) {
3663 return false;
3664 }
3665
3666 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
3667 *confidence = 0.4f;
3668
3669 if (moovAtomEndOffset >= 0) {
3670 *meta = new AMessage;
3671 (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
3672
3673 ALOGV("found metadata size: %lld", moovAtomEndOffset);
3674 }
3675
3676 return true;
3677 }
3678
SniffMPEG4(const sp<DataSource> & source,String8 * mimeType,float * confidence,sp<AMessage> * meta)3679 bool SniffMPEG4(
3680 const sp<DataSource> &source, String8 *mimeType, float *confidence,
3681 sp<AMessage> *meta) {
3682 if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
3683 return true;
3684 }
3685
3686 if (LegacySniffMPEG4(source, mimeType, confidence)) {
3687 ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
3688 return true;
3689 }
3690
3691 return false;
3692 }
3693
3694 } // namespace android
3695