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