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