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