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