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