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