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