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