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