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