MPEG4Extractor.cpp revision 3d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0
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/MediaTrack.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 MediaTrack {
69public:
70    // Caller retains ownership of both "dataSource" and "sampleTable".
71    MPEG4Source(MetaDataBase &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(MetaDataBase *params = NULL);
82    virtual status_t stop();
83
84    virtual status_t getFormat(MetaDataBase &);
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    MetaDataBase &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    ALOGV("mime=%s, mPreferHeif=%d", mime, mPreferHeif);
358}
359
360MPEG4Extractor::~MPEG4Extractor() {
361    Track *track = mFirstTrack;
362    while (track) {
363        Track *next = track->next;
364
365        delete track;
366        track = next;
367    }
368    mFirstTrack = mLastTrack = NULL;
369
370    for (size_t i = 0; i < mPssh.size(); i++) {
371        delete [] mPssh[i].data;
372    }
373    mPssh.clear();
374
375    delete mCachedSource;
376}
377
378uint32_t MPEG4Extractor::flags() const {
379    return CAN_PAUSE |
380            ((mMoofOffset == 0 || mSidxEntries.size() != 0) ?
381                    (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
382}
383
384status_t MPEG4Extractor::getMetaData(MetaDataBase &meta) {
385    status_t err;
386    if ((err = readMetaData()) != OK) {
387        return UNKNOWN_ERROR;
388    }
389    meta = mFileMetaData;
390    return OK;
391}
392
393size_t MPEG4Extractor::countTracks() {
394    status_t err;
395    if ((err = readMetaData()) != OK) {
396        ALOGV("MPEG4Extractor::countTracks: no tracks");
397        return 0;
398    }
399
400    size_t n = 0;
401    Track *track = mFirstTrack;
402    while (track) {
403        ++n;
404        track = track->next;
405    }
406
407    ALOGV("MPEG4Extractor::countTracks: %zu tracks", n);
408    return n;
409}
410
411status_t MPEG4Extractor::getTrackMetaData(
412        MetaDataBase &meta,
413        size_t index, uint32_t flags) {
414    status_t err;
415    if ((err = readMetaData()) != OK) {
416        return UNKNOWN_ERROR;
417    }
418
419    Track *track = mFirstTrack;
420    while (index > 0) {
421        if (track == NULL) {
422            return UNKNOWN_ERROR;
423        }
424
425        track = track->next;
426        --index;
427    }
428
429    if (track == NULL) {
430        return UNKNOWN_ERROR;
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    meta = track->meta;
556    return OK;
557}
558
559status_t MPEG4Extractor::readMetaData() {
560    if (mInitCheck != NO_INIT) {
561        return mInitCheck;
562    }
563
564    off64_t offset = 0;
565    status_t err;
566    bool sawMoovOrSidx = false;
567
568    while (!((mHasMoovBox && sawMoovOrSidx && (mMdatFound || mMoofFound)) ||
569             (mIsHeif && (mPreferHeif || !mHasMoovBox) &&
570                     (mItemTable != NULL) && mItemTable->isValid()))) {
571        off64_t orig_offset = offset;
572        err = parseChunk(&offset, 0);
573
574        if (err != OK && err != UNKNOWN_ERROR) {
575            break;
576        } else if (offset <= orig_offset) {
577            // only continue parsing if the offset was advanced,
578            // otherwise we might end up in an infinite loop
579            ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset);
580            err = ERROR_MALFORMED;
581            break;
582        } else if (err == UNKNOWN_ERROR) {
583            sawMoovOrSidx = true;
584        }
585    }
586
587    if (mIsHeif && (mItemTable != NULL) && (mItemTable->countImages() > 0)) {
588        for (uint32_t imageIndex = 0;
589                imageIndex < mItemTable->countImages(); imageIndex++) {
590            sp<MetaData> meta = mItemTable->getImageMeta(imageIndex);
591            if (meta == NULL) {
592                ALOGE("heif image %u has no meta!", imageIndex);
593                continue;
594            }
595            // Some heif files advertise image sequence brands (eg. 'hevc') in
596            // ftyp box, but don't have any valid tracks in them. Instead of
597            // reporting the entire file as malformed, we override the error
598            // to allow still images to be extracted.
599            if (err != OK) {
600                ALOGW("Extracting still images only");
601                err = OK;
602            }
603
604            ALOGV("adding HEIF image track %u", imageIndex);
605            Track *track = new Track;
606            track->next = NULL;
607            if (mLastTrack != NULL) {
608                mLastTrack->next = track;
609            } else {
610                mFirstTrack = track;
611            }
612            mLastTrack = track;
613
614            track->meta = *(meta.get());
615            track->meta.setInt32(kKeyTrackID, imageIndex);
616            track->includes_expensive_metadata = false;
617            track->skipTrack = false;
618            track->timescale = 0;
619        }
620    }
621
622    if (mInitCheck == OK) {
623        if (findTrackByMimePrefix("video/") != NULL) {
624            mFileMetaData.setCString(
625                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
626        } else if (findTrackByMimePrefix("audio/") != NULL) {
627            mFileMetaData.setCString(kKeyMIMEType, "audio/mp4");
628        } else if (findTrackByMimePrefix(
629                MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) != NULL) {
630            mFileMetaData.setCString(
631                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_HEIF);
632        } else {
633            mFileMetaData.setCString(kKeyMIMEType, "application/octet-stream");
634        }
635    } else {
636        mInitCheck = err;
637    }
638
639    CHECK_NE(err, (status_t)NO_INIT);
640
641    // copy pssh data into file metadata
642    uint64_t psshsize = 0;
643    for (size_t i = 0; i < mPssh.size(); i++) {
644        psshsize += 20 + mPssh[i].datalen;
645    }
646    if (psshsize > 0 && psshsize <= UINT32_MAX) {
647        char *buf = (char*)malloc(psshsize);
648        if (!buf) {
649            ALOGE("b/28471206");
650            return NO_MEMORY;
651        }
652        char *ptr = buf;
653        for (size_t i = 0; i < mPssh.size(); i++) {
654            memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
655            memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
656            ptr += (20 + mPssh[i].datalen);
657        }
658        mFileMetaData.setData(kKeyPssh, 'pssh', buf, psshsize);
659        free(buf);
660    }
661
662    return mInitCheck;
663}
664
665struct PathAdder {
666    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
667        : mPath(path) {
668        mPath->push(chunkType);
669    }
670
671    ~PathAdder() {
672        mPath->pop();
673    }
674
675private:
676    Vector<uint32_t> *mPath;
677
678    PathAdder(const PathAdder &);
679    PathAdder &operator=(const PathAdder &);
680};
681
682static bool underMetaDataPath(const Vector<uint32_t> &path) {
683    return path.size() >= 5
684        && path[0] == FOURCC('m', 'o', 'o', 'v')
685        && path[1] == FOURCC('u', 'd', 't', 'a')
686        && path[2] == FOURCC('m', 'e', 't', 'a')
687        && path[3] == FOURCC('i', 'l', 's', 't');
688}
689
690static bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) {
691    return path.size() >= 2
692            && path[0] == FOURCC('m', 'o', 'o', 'v')
693            && path[1] == FOURCC('m', 'e', 't', 'a')
694            && (depth == 2
695            || (depth == 3
696                    && (path[2] == FOURCC('h', 'd', 'l', 'r')
697                    ||  path[2] == FOURCC('i', 'l', 's', 't')
698                    ||  path[2] == FOURCC('k', 'e', 'y', 's'))));
699}
700
701// Given a time in seconds since Jan 1 1904, produce a human-readable string.
702static bool convertTimeToDate(int64_t time_1904, String8 *s) {
703    // delta between mpeg4 time and unix epoch time
704    static const int64_t delta = (((66 * 365 + 17) * 24) * 3600);
705    if (time_1904 < INT64_MIN + delta) {
706        return false;
707    }
708    time_t time_1970 = time_1904 - delta;
709
710    char tmp[32];
711    struct tm* tm = gmtime(&time_1970);
712    if (tm != NULL &&
713            strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
714        s->setTo(tmp);
715        return true;
716    }
717    return false;
718}
719
720status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
721    ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth);
722
723    if (*offset < 0) {
724        ALOGE("b/23540914");
725        return ERROR_MALFORMED;
726    }
727    if (depth > 100) {
728        ALOGE("b/27456299");
729        return ERROR_MALFORMED;
730    }
731    uint32_t hdr[2];
732    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
733        return ERROR_IO;
734    }
735    uint64_t chunk_size = ntohl(hdr[0]);
736    int32_t chunk_type = ntohl(hdr[1]);
737    off64_t data_offset = *offset + 8;
738
739    if (chunk_size == 1) {
740        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
741            return ERROR_IO;
742        }
743        chunk_size = ntoh64(chunk_size);
744        data_offset += 8;
745
746        if (chunk_size < 16) {
747            // The smallest valid chunk is 16 bytes long in this case.
748            return ERROR_MALFORMED;
749        }
750    } else if (chunk_size == 0) {
751        if (depth == 0) {
752            // atom extends to end of file
753            off64_t sourceSize;
754            if (mDataSource->getSize(&sourceSize) == OK) {
755                chunk_size = (sourceSize - *offset);
756            } else {
757                // XXX could we just pick a "sufficiently large" value here?
758                ALOGE("atom size is 0, and data source has no size");
759                return ERROR_MALFORMED;
760            }
761        } else {
762            // not allowed for non-toplevel atoms, skip it
763            *offset += 4;
764            return OK;
765        }
766    } else if (chunk_size < 8) {
767        // The smallest valid chunk is 8 bytes long.
768        ALOGE("invalid chunk size: %" PRIu64, chunk_size);
769        return ERROR_MALFORMED;
770    }
771
772    char chunk[5];
773    MakeFourCCString(chunk_type, chunk);
774    ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth);
775
776    if (kUseHexDump) {
777        static const char kWhitespace[] = "                                        ";
778        const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
779        printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size);
780
781        char buffer[256];
782        size_t n = chunk_size;
783        if (n > sizeof(buffer)) {
784            n = sizeof(buffer);
785        }
786        if (mDataSource->readAt(*offset, buffer, n)
787                < (ssize_t)n) {
788            return ERROR_IO;
789        }
790
791        hexdump(buffer, n);
792    }
793
794    PathAdder autoAdder(&mPath, chunk_type);
795
796    // (data_offset - *offset) is either 8 or 16
797    off64_t chunk_data_size = chunk_size - (data_offset - *offset);
798    if (chunk_data_size < 0) {
799        ALOGE("b/23540914");
800        return ERROR_MALFORMED;
801    }
802    if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) {
803        char errMsg[100];
804        sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
805        ALOGE("%s (b/28615448)", errMsg);
806        android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg));
807        return ERROR_MALFORMED;
808    }
809
810    if (chunk_type != FOURCC('c', 'p', 'r', 't')
811            && chunk_type != FOURCC('c', 'o', 'v', 'r')
812            && mPath.size() == 5 && underMetaDataPath(mPath)) {
813        off64_t stop_offset = *offset + chunk_size;
814        *offset = data_offset;
815        while (*offset < stop_offset) {
816            status_t err = parseChunk(offset, depth + 1);
817            if (err != OK) {
818                return err;
819            }
820        }
821
822        if (*offset != stop_offset) {
823            return ERROR_MALFORMED;
824        }
825
826        return OK;
827    }
828
829    switch(chunk_type) {
830        case FOURCC('m', 'o', 'o', 'v'):
831        case FOURCC('t', 'r', 'a', 'k'):
832        case FOURCC('m', 'd', 'i', 'a'):
833        case FOURCC('m', 'i', 'n', 'f'):
834        case FOURCC('d', 'i', 'n', 'f'):
835        case FOURCC('s', 't', 'b', 'l'):
836        case FOURCC('m', 'v', 'e', 'x'):
837        case FOURCC('m', 'o', 'o', 'f'):
838        case FOURCC('t', 'r', 'a', 'f'):
839        case FOURCC('m', 'f', 'r', 'a'):
840        case FOURCC('u', 'd', 't', 'a'):
841        case FOURCC('i', 'l', 's', 't'):
842        case FOURCC('s', 'i', 'n', 'f'):
843        case FOURCC('s', 'c', 'h', 'i'):
844        case FOURCC('e', 'd', 't', 's'):
845        case FOURCC('w', 'a', 'v', 'e'):
846        {
847            if (chunk_type == FOURCC('m', 'o', 'o', 'v') && depth != 0) {
848                ALOGE("moov: depth %d", depth);
849                return ERROR_MALFORMED;
850            }
851
852            if (chunk_type == FOURCC('m', 'o', 'o', 'v') && mInitCheck == OK) {
853                ALOGE("duplicate moov");
854                return ERROR_MALFORMED;
855            }
856
857            if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) {
858                // store the offset of the first segment
859                mMoofFound = true;
860                mMoofOffset = *offset;
861            }
862
863            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
864                ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
865
866                if (mDataSource->flags()
867                        & (DataSourceBase::kWantsPrefetching
868                            | DataSourceBase::kIsCachingDataSource)) {
869                    CachedRangedDataSource *cachedSource =
870                        new CachedRangedDataSource(mDataSource);
871
872                    if (cachedSource->setCachedRange(
873                            *offset, chunk_size,
874                            mCachedSource != NULL /* assume ownership on success */) == OK) {
875                        mDataSource = mCachedSource = cachedSource;
876                    } else {
877                        delete cachedSource;
878                    }
879                }
880
881                if (mLastTrack == NULL) {
882                    return ERROR_MALFORMED;
883                }
884
885                mLastTrack->sampleTable = new SampleTable(mDataSource);
886            }
887
888            bool isTrack = false;
889            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
890                if (depth != 1) {
891                    ALOGE("trak: depth %d", depth);
892                    return ERROR_MALFORMED;
893                }
894                isTrack = true;
895
896                ALOGV("adding new track");
897                Track *track = new Track;
898                track->next = NULL;
899                if (mLastTrack) {
900                    mLastTrack->next = track;
901                } else {
902                    mFirstTrack = track;
903                }
904                mLastTrack = track;
905
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            ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64,
2210                  chunk_data_size, data_offset);
2211
2212            if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) {
2213                return ERROR_MALFORMED;
2214            }
2215            sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
2216            if (buffer->data() == NULL) {
2217                ALOGE("b/28471206");
2218                return NO_MEMORY;
2219            }
2220            if (mDataSource->readAt(
2221                data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
2222                return ERROR_IO;
2223            }
2224            const int kSkipBytesOfDataBox = 16;
2225            if (chunk_data_size <= kSkipBytesOfDataBox) {
2226                return ERROR_MALFORMED;
2227            }
2228
2229            mFileMetaData.setData(
2230                kKeyAlbumArt, MetaData::TYPE_NONE,
2231                buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
2232
2233            break;
2234        }
2235
2236        case FOURCC('c', 'o', 'l', 'r'):
2237        {
2238            *offset += chunk_size;
2239            // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
2240            // ignore otherwise
2241            if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
2242                status_t err = parseColorInfo(data_offset, chunk_data_size);
2243                if (err != OK) {
2244                    return err;
2245                }
2246            }
2247
2248            break;
2249        }
2250
2251        case FOURCC('t', 'i', 't', 'l'):
2252        case FOURCC('p', 'e', 'r', 'f'):
2253        case FOURCC('a', 'u', 't', 'h'):
2254        case FOURCC('g', 'n', 'r', 'e'):
2255        case FOURCC('a', 'l', 'b', 'm'):
2256        case FOURCC('y', 'r', 'r', 'c'):
2257        {
2258            *offset += chunk_size;
2259
2260            status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
2261
2262            if (err != OK) {
2263                return err;
2264            }
2265
2266            break;
2267        }
2268
2269        case FOURCC('I', 'D', '3', '2'):
2270        {
2271            *offset += chunk_size;
2272
2273            if (chunk_data_size < 6) {
2274                return ERROR_MALFORMED;
2275            }
2276
2277            parseID3v2MetaData(data_offset + 6);
2278
2279            break;
2280        }
2281
2282        case FOURCC('-', '-', '-', '-'):
2283        {
2284            mLastCommentMean.clear();
2285            mLastCommentName.clear();
2286            mLastCommentData.clear();
2287            *offset += chunk_size;
2288            break;
2289        }
2290
2291        case FOURCC('s', 'i', 'd', 'x'):
2292        {
2293            status_t err = parseSegmentIndex(data_offset, chunk_data_size);
2294            if (err != OK) {
2295                return err;
2296            }
2297            *offset += chunk_size;
2298            return UNKNOWN_ERROR; // stop parsing after sidx
2299        }
2300
2301        case FOURCC('a', 'c', '-', '3'):
2302        {
2303            *offset += chunk_size;
2304            return parseAC3SampleEntry(data_offset);
2305        }
2306
2307        case FOURCC('f', 't', 'y', 'p'):
2308        {
2309            if (chunk_data_size < 8 || depth != 0) {
2310                return ERROR_MALFORMED;
2311            }
2312
2313            off64_t stop_offset = *offset + chunk_size;
2314            uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4;
2315            std::set<uint32_t> brandSet;
2316            for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
2317                if (i == 1) {
2318                    // Skip this index, it refers to the minorVersion,
2319                    // not a brand.
2320                    continue;
2321                }
2322
2323                uint32_t brand;
2324                if (mDataSource->readAt(data_offset + 4 * i, &brand, 4) < 4) {
2325                    return ERROR_MALFORMED;
2326                }
2327
2328                brand = ntohl(brand);
2329                brandSet.insert(brand);
2330            }
2331
2332            if (brandSet.count(FOURCC('q', 't', ' ', ' ')) > 0) {
2333                mIsQT = true;
2334            } else {
2335                if (brandSet.count(FOURCC('m', 'i', 'f', '1')) > 0
2336                 && brandSet.count(FOURCC('h', 'e', 'i', 'c')) > 0) {
2337                    ALOGV("identified HEIF image");
2338
2339                    mIsHeif = true;
2340                    brandSet.erase(FOURCC('m', 'i', 'f', '1'));
2341                    brandSet.erase(FOURCC('h', 'e', 'i', 'c'));
2342                }
2343
2344                if (!brandSet.empty()) {
2345                    // This means that the file should have moov box.
2346                    // It could be any iso files (mp4, heifs, etc.)
2347                    mHasMoovBox = true;
2348                    ALOGV("identified HEIF image with other tracks");
2349                }
2350            }
2351
2352            *offset = stop_offset;
2353
2354            break;
2355        }
2356
2357        default:
2358        {
2359            // check if we're parsing 'ilst' for meta keys
2360            // if so, treat type as a number (key-id).
2361            if (underQTMetaPath(mPath, 3)) {
2362                status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
2363                if (err != OK) {
2364                    return err;
2365                }
2366            }
2367
2368            *offset += chunk_size;
2369            break;
2370        }
2371    }
2372
2373    return OK;
2374}
2375
2376status_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) {
2377    // skip 16 bytes:
2378    //  + 6-byte reserved,
2379    //  + 2-byte data reference index,
2380    //  + 8-byte reserved
2381    offset += 16;
2382    uint16_t channelCount;
2383    if (!mDataSource->getUInt16(offset, &channelCount)) {
2384        return ERROR_MALFORMED;
2385    }
2386    // skip 8 bytes:
2387    //  + 2-byte channelCount,
2388    //  + 2-byte sample size,
2389    //  + 4-byte reserved
2390    offset += 8;
2391    uint16_t sampleRate;
2392    if (!mDataSource->getUInt16(offset, &sampleRate)) {
2393        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate");
2394        return ERROR_MALFORMED;
2395    }
2396
2397    // skip 4 bytes:
2398    //  + 2-byte sampleRate,
2399    //  + 2-byte reserved
2400    offset += 4;
2401    return parseAC3SpecificBox(offset, sampleRate);
2402}
2403
2404status_t MPEG4Extractor::parseAC3SpecificBox(
2405        off64_t offset, uint16_t sampleRate) {
2406    uint32_t size;
2407    // + 4-byte size
2408    // + 4-byte type
2409    // + 3-byte payload
2410    const uint32_t kAC3SpecificBoxSize = 11;
2411    if (!mDataSource->getUInt32(offset, &size) || size < kAC3SpecificBoxSize) {
2412        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read specific box size");
2413        return ERROR_MALFORMED;
2414    }
2415
2416    offset += 4;
2417    uint32_t type;
2418    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'a', 'c', '3')) {
2419        ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3");
2420        return ERROR_MALFORMED;
2421    }
2422
2423    offset += 4;
2424    const uint32_t kAC3SpecificBoxPayloadSize = 3;
2425    uint8_t chunk[kAC3SpecificBoxPayloadSize];
2426    if (mDataSource->readAt(offset, chunk, sizeof(chunk)) != sizeof(chunk)) {
2427        ALOGE("MPEG4Extractor: error while reading ac-3 specific block: bitstream fields");
2428        return ERROR_MALFORMED;
2429    }
2430
2431    ABitReader br(chunk, sizeof(chunk));
2432    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
2433    static const unsigned sampleRateTable[] = {48000, 44100, 32000};
2434
2435    unsigned fscod = br.getBits(2);
2436    if (fscod == 3) {
2437        ALOGE("Incorrect fscod (3) in AC3 header");
2438        return ERROR_MALFORMED;
2439    }
2440    unsigned boxSampleRate = sampleRateTable[fscod];
2441    if (boxSampleRate != sampleRate) {
2442        ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
2443            boxSampleRate, sampleRate);
2444        return ERROR_MALFORMED;
2445    }
2446
2447    unsigned bsid = br.getBits(5);
2448    if (bsid > 8) {
2449        ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
2450        return ERROR_MALFORMED;
2451    }
2452
2453    // skip
2454    unsigned bsmod __unused = br.getBits(3);
2455
2456    unsigned acmod = br.getBits(3);
2457    unsigned lfeon = br.getBits(1);
2458    unsigned channelCount = channelCountTable[acmod] + lfeon;
2459
2460    if (mLastTrack == NULL) {
2461        return ERROR_MALFORMED;
2462    }
2463    mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
2464    mLastTrack->meta.setInt32(kKeyChannelCount, channelCount);
2465    mLastTrack->meta.setInt32(kKeySampleRate, sampleRate);
2466    return OK;
2467}
2468
2469status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
2470  ALOGV("MPEG4Extractor::parseSegmentIndex");
2471
2472    if (size < 12) {
2473      return -EINVAL;
2474    }
2475
2476    uint32_t flags;
2477    if (!mDataSource->getUInt32(offset, &flags)) {
2478        return ERROR_MALFORMED;
2479    }
2480
2481    uint32_t version = flags >> 24;
2482    flags &= 0xffffff;
2483
2484    ALOGV("sidx version %d", version);
2485
2486    uint32_t referenceId;
2487    if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
2488        return ERROR_MALFORMED;
2489    }
2490
2491    uint32_t timeScale;
2492    if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
2493        return ERROR_MALFORMED;
2494    }
2495    ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
2496    if (timeScale == 0)
2497        return ERROR_MALFORMED;
2498
2499    uint64_t earliestPresentationTime;
2500    uint64_t firstOffset;
2501
2502    offset += 12;
2503    size -= 12;
2504
2505    if (version == 0) {
2506        if (size < 8) {
2507            return -EINVAL;
2508        }
2509        uint32_t tmp;
2510        if (!mDataSource->getUInt32(offset, &tmp)) {
2511            return ERROR_MALFORMED;
2512        }
2513        earliestPresentationTime = tmp;
2514        if (!mDataSource->getUInt32(offset + 4, &tmp)) {
2515            return ERROR_MALFORMED;
2516        }
2517        firstOffset = tmp;
2518        offset += 8;
2519        size -= 8;
2520    } else {
2521        if (size < 16) {
2522            return -EINVAL;
2523        }
2524        if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
2525            return ERROR_MALFORMED;
2526        }
2527        if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
2528            return ERROR_MALFORMED;
2529        }
2530        offset += 16;
2531        size -= 16;
2532    }
2533    ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset);
2534
2535    if (size < 4) {
2536        return -EINVAL;
2537    }
2538
2539    uint16_t referenceCount;
2540    if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
2541        return ERROR_MALFORMED;
2542    }
2543    offset += 4;
2544    size -= 4;
2545    ALOGV("refcount: %d", referenceCount);
2546
2547    if (size < referenceCount * 12) {
2548        return -EINVAL;
2549    }
2550
2551    uint64_t total_duration = 0;
2552    for (unsigned int i = 0; i < referenceCount; i++) {
2553        uint32_t d1, d2, d3;
2554
2555        if (!mDataSource->getUInt32(offset, &d1) ||     // size
2556            !mDataSource->getUInt32(offset + 4, &d2) || // duration
2557            !mDataSource->getUInt32(offset + 8, &d3)) { // flags
2558            return ERROR_MALFORMED;
2559        }
2560
2561        if (d1 & 0x80000000) {
2562            ALOGW("sub-sidx boxes not supported yet");
2563        }
2564        bool sap = d3 & 0x80000000;
2565        uint32_t saptype = (d3 >> 28) & 7;
2566        if (!sap || (saptype != 1 && saptype != 2)) {
2567            // type 1 and 2 are sync samples
2568            ALOGW("not a stream access point, or unsupported type: %08x", d3);
2569        }
2570        total_duration += d2;
2571        offset += 12;
2572        ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
2573        SidxEntry se;
2574        se.mSize = d1 & 0x7fffffff;
2575        se.mDurationUs = 1000000LL * d2 / timeScale;
2576        mSidxEntries.add(se);
2577    }
2578
2579    uint64_t sidxDuration = total_duration * 1000000 / timeScale;
2580
2581    if (mLastTrack == NULL)
2582        return ERROR_MALFORMED;
2583
2584    int64_t metaDuration;
2585    if (!mLastTrack->meta.findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
2586        mLastTrack->meta.setInt64(kKeyDuration, sidxDuration);
2587    }
2588    return OK;
2589}
2590
2591status_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) {
2592    if (size < 8) {
2593        return ERROR_MALFORMED;
2594    }
2595
2596    uint32_t count;
2597    if (!mDataSource->getUInt32(offset + 4, &count)) {
2598        return ERROR_MALFORMED;
2599    }
2600
2601    if (mMetaKeyMap.size() > 0) {
2602        ALOGW("'keys' atom seen again, discarding existing entries");
2603        mMetaKeyMap.clear();
2604    }
2605
2606    off64_t keyOffset = offset + 8;
2607    off64_t stopOffset = offset + size;
2608    for (size_t i = 1; i <= count; i++) {
2609        if (keyOffset + 8 > stopOffset) {
2610            return ERROR_MALFORMED;
2611        }
2612
2613        uint32_t keySize;
2614        if (!mDataSource->getUInt32(keyOffset, &keySize)
2615                || keySize < 8
2616                || keyOffset + keySize > stopOffset) {
2617            return ERROR_MALFORMED;
2618        }
2619
2620        uint32_t type;
2621        if (!mDataSource->getUInt32(keyOffset + 4, &type)
2622                || type != FOURCC('m', 'd', 't', 'a')) {
2623            return ERROR_MALFORMED;
2624        }
2625
2626        keySize -= 8;
2627        keyOffset += 8;
2628
2629        sp<ABuffer> keyData = new ABuffer(keySize);
2630        if (keyData->data() == NULL) {
2631            return ERROR_MALFORMED;
2632        }
2633        if (mDataSource->readAt(
2634                keyOffset, keyData->data(), keySize) < (ssize_t) keySize) {
2635            return ERROR_MALFORMED;
2636        }
2637
2638        AString key((const char *)keyData->data(), keySize);
2639        mMetaKeyMap.add(i, key);
2640
2641        keyOffset += keySize;
2642    }
2643    return OK;
2644}
2645
2646status_t MPEG4Extractor::parseQTMetaVal(
2647        int32_t keyId, off64_t offset, size_t size) {
2648    ssize_t index = mMetaKeyMap.indexOfKey(keyId);
2649    if (index < 0) {
2650        // corresponding key is not present, ignore
2651        return ERROR_MALFORMED;
2652    }
2653
2654    if (size <= 16) {
2655        return ERROR_MALFORMED;
2656    }
2657    uint32_t dataSize;
2658    if (!mDataSource->getUInt32(offset, &dataSize)
2659            || dataSize > size || dataSize <= 16) {
2660        return ERROR_MALFORMED;
2661    }
2662    uint32_t atomFourCC;
2663    if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
2664            || atomFourCC != FOURCC('d', 'a', 't', 'a')) {
2665        return ERROR_MALFORMED;
2666    }
2667    uint32_t dataType;
2668    if (!mDataSource->getUInt32(offset + 8, &dataType)
2669            || ((dataType & 0xff000000) != 0)) {
2670        // not well-known type
2671        return ERROR_MALFORMED;
2672    }
2673
2674    dataSize -= 16;
2675    offset += 16;
2676
2677    if (dataType == 23 && dataSize >= 4) {
2678        // BE Float32
2679        uint32_t val;
2680        if (!mDataSource->getUInt32(offset, &val)) {
2681            return ERROR_MALFORMED;
2682        }
2683        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
2684            mFileMetaData.setFloat(kKeyCaptureFramerate, *(float *)&val);
2685        }
2686    } else if (dataType == 67 && dataSize >= 4) {
2687        // BE signed int32
2688        uint32_t val;
2689        if (!mDataSource->getUInt32(offset, &val)) {
2690            return ERROR_MALFORMED;
2691        }
2692        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
2693            mFileMetaData.setInt32(kKeyTemporalLayerCount, val);
2694        }
2695    } else {
2696        // add more keys if needed
2697        ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
2698    }
2699
2700    return OK;
2701}
2702
2703status_t MPEG4Extractor::parseTrackHeader(
2704        off64_t data_offset, off64_t data_size) {
2705    if (data_size < 4) {
2706        return ERROR_MALFORMED;
2707    }
2708
2709    uint8_t version;
2710    if (mDataSource->readAt(data_offset, &version, 1) < 1) {
2711        return ERROR_IO;
2712    }
2713
2714    size_t dynSize = (version == 1) ? 36 : 24;
2715
2716    uint8_t buffer[36 + 60];
2717
2718    if (data_size != (off64_t)dynSize + 60) {
2719        return ERROR_MALFORMED;
2720    }
2721
2722    if (mDataSource->readAt(
2723                data_offset, buffer, data_size) < (ssize_t)data_size) {
2724        return ERROR_IO;
2725    }
2726
2727    uint64_t ctime __unused, mtime __unused, duration __unused;
2728    int32_t id;
2729
2730    if (version == 1) {
2731        ctime = U64_AT(&buffer[4]);
2732        mtime = U64_AT(&buffer[12]);
2733        id = U32_AT(&buffer[20]);
2734        duration = U64_AT(&buffer[28]);
2735    } else if (version == 0) {
2736        ctime = U32_AT(&buffer[4]);
2737        mtime = U32_AT(&buffer[8]);
2738        id = U32_AT(&buffer[12]);
2739        duration = U32_AT(&buffer[20]);
2740    } else {
2741        return ERROR_UNSUPPORTED;
2742    }
2743
2744    if (mLastTrack == NULL)
2745        return ERROR_MALFORMED;
2746
2747    mLastTrack->meta.setInt32(kKeyTrackID, id);
2748
2749    size_t matrixOffset = dynSize + 16;
2750    int32_t a00 = U32_AT(&buffer[matrixOffset]);
2751    int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
2752    int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
2753    int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
2754
2755#if 0
2756    int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
2757    int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
2758
2759    ALOGI("x' = %.2f * x + %.2f * y + %.2f",
2760         a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
2761    ALOGI("y' = %.2f * x + %.2f * y + %.2f",
2762         a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
2763#endif
2764
2765    uint32_t rotationDegrees;
2766
2767    static const int32_t kFixedOne = 0x10000;
2768    if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
2769        // Identity, no rotation
2770        rotationDegrees = 0;
2771    } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
2772        rotationDegrees = 90;
2773    } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
2774        rotationDegrees = 270;
2775    } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
2776        rotationDegrees = 180;
2777    } else {
2778        ALOGW("We only support 0,90,180,270 degree rotation matrices");
2779        rotationDegrees = 0;
2780    }
2781
2782    if (rotationDegrees != 0) {
2783        mLastTrack->meta.setInt32(kKeyRotation, rotationDegrees);
2784    }
2785
2786    // Handle presentation display size, which could be different
2787    // from the image size indicated by kKeyWidth and kKeyHeight.
2788    uint32_t width = U32_AT(&buffer[dynSize + 52]);
2789    uint32_t height = U32_AT(&buffer[dynSize + 56]);
2790    mLastTrack->meta.setInt32(kKeyDisplayWidth, width >> 16);
2791    mLastTrack->meta.setInt32(kKeyDisplayHeight, height >> 16);
2792
2793    return OK;
2794}
2795
2796status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
2797    if (size == 0) {
2798        return OK;
2799    }
2800
2801    if (size < 4 || size == SIZE_MAX) {
2802        return ERROR_MALFORMED;
2803    }
2804
2805    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
2806    if (buffer == NULL) {
2807        return ERROR_MALFORMED;
2808    }
2809    if (mDataSource->readAt(
2810                offset, buffer, size) != (ssize_t)size) {
2811        delete[] buffer;
2812        buffer = NULL;
2813
2814        return ERROR_IO;
2815    }
2816
2817    uint32_t flags = U32_AT(buffer);
2818
2819    uint32_t metadataKey = 0;
2820    char chunk[5];
2821    MakeFourCCString(mPath[4], chunk);
2822    ALOGV("meta: %s @ %lld", chunk, (long long)offset);
2823    switch ((int32_t)mPath[4]) {
2824        case FOURCC(0xa9, 'a', 'l', 'b'):
2825        {
2826            metadataKey = kKeyAlbum;
2827            break;
2828        }
2829        case FOURCC(0xa9, 'A', 'R', 'T'):
2830        {
2831            metadataKey = kKeyArtist;
2832            break;
2833        }
2834        case FOURCC('a', 'A', 'R', 'T'):
2835        {
2836            metadataKey = kKeyAlbumArtist;
2837            break;
2838        }
2839        case FOURCC(0xa9, 'd', 'a', 'y'):
2840        {
2841            metadataKey = kKeyYear;
2842            break;
2843        }
2844        case FOURCC(0xa9, 'n', 'a', 'm'):
2845        {
2846            metadataKey = kKeyTitle;
2847            break;
2848        }
2849        case FOURCC(0xa9, 'w', 'r', 't'):
2850        {
2851            metadataKey = kKeyWriter;
2852            break;
2853        }
2854        case FOURCC('c', 'o', 'v', 'r'):
2855        {
2856            metadataKey = kKeyAlbumArt;
2857            break;
2858        }
2859        case FOURCC('g', 'n', 'r', 'e'):
2860        {
2861            metadataKey = kKeyGenre;
2862            break;
2863        }
2864        case FOURCC(0xa9, 'g', 'e', 'n'):
2865        {
2866            metadataKey = kKeyGenre;
2867            break;
2868        }
2869        case FOURCC('c', 'p', 'i', 'l'):
2870        {
2871            if (size == 9 && flags == 21) {
2872                char tmp[16];
2873                sprintf(tmp, "%d",
2874                        (int)buffer[size - 1]);
2875
2876                mFileMetaData.setCString(kKeyCompilation, tmp);
2877            }
2878            break;
2879        }
2880        case FOURCC('t', 'r', 'k', 'n'):
2881        {
2882            if (size == 16 && flags == 0) {
2883                char tmp[16];
2884                uint16_t* pTrack = (uint16_t*)&buffer[10];
2885                uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
2886                sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
2887
2888                mFileMetaData.setCString(kKeyCDTrackNumber, tmp);
2889            }
2890            break;
2891        }
2892        case FOURCC('d', 'i', 's', 'k'):
2893        {
2894            if ((size == 14 || size == 16) && flags == 0) {
2895                char tmp[16];
2896                uint16_t* pDisc = (uint16_t*)&buffer[10];
2897                uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
2898                sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
2899
2900                mFileMetaData.setCString(kKeyDiscNumber, tmp);
2901            }
2902            break;
2903        }
2904        case FOURCC('-', '-', '-', '-'):
2905        {
2906            buffer[size] = '\0';
2907            switch (mPath[5]) {
2908                case FOURCC('m', 'e', 'a', 'n'):
2909                    mLastCommentMean.setTo((const char *)buffer + 4);
2910                    break;
2911                case FOURCC('n', 'a', 'm', 'e'):
2912                    mLastCommentName.setTo((const char *)buffer + 4);
2913                    break;
2914                case FOURCC('d', 'a', 't', 'a'):
2915                    if (size < 8) {
2916                        delete[] buffer;
2917                        buffer = NULL;
2918                        ALOGE("b/24346430");
2919                        return ERROR_MALFORMED;
2920                    }
2921                    mLastCommentData.setTo((const char *)buffer + 8);
2922                    break;
2923            }
2924
2925            // Once we have a set of mean/name/data info, go ahead and process
2926            // it to see if its something we are interested in.  Whether or not
2927            // were are interested in the specific tag, make sure to clear out
2928            // the set so we can be ready to process another tuple should one
2929            // show up later in the file.
2930            if ((mLastCommentMean.length() != 0) &&
2931                (mLastCommentName.length() != 0) &&
2932                (mLastCommentData.length() != 0)) {
2933
2934                if (mLastCommentMean == "com.apple.iTunes"
2935                        && mLastCommentName == "iTunSMPB") {
2936                    int32_t delay, padding;
2937                    if (sscanf(mLastCommentData,
2938                               " %*x %x %x %*x", &delay, &padding) == 2) {
2939                        if (mLastTrack == NULL) {
2940                            delete[] buffer;
2941                            return ERROR_MALFORMED;
2942                        }
2943
2944                        mLastTrack->meta.setInt32(kKeyEncoderDelay, delay);
2945                        mLastTrack->meta.setInt32(kKeyEncoderPadding, padding);
2946                    }
2947                }
2948
2949                mLastCommentMean.clear();
2950                mLastCommentName.clear();
2951                mLastCommentData.clear();
2952            }
2953            break;
2954        }
2955
2956        default:
2957            break;
2958    }
2959
2960    if (size >= 8 && metadataKey && !mFileMetaData.hasData(metadataKey)) {
2961        if (metadataKey == kKeyAlbumArt) {
2962            mFileMetaData.setData(
2963                    kKeyAlbumArt, MetaData::TYPE_NONE,
2964                    buffer + 8, size - 8);
2965        } else if (metadataKey == kKeyGenre) {
2966            if (flags == 0) {
2967                // uint8_t genre code, iTunes genre codes are
2968                // the standard id3 codes, except they start
2969                // at 1 instead of 0 (e.g. Pop is 14, not 13)
2970                // We use standard id3 numbering, so subtract 1.
2971                int genrecode = (int)buffer[size - 1];
2972                genrecode--;
2973                if (genrecode < 0) {
2974                    genrecode = 255; // reserved for 'unknown genre'
2975                }
2976                char genre[10];
2977                sprintf(genre, "%d", genrecode);
2978
2979                mFileMetaData.setCString(metadataKey, genre);
2980            } else if (flags == 1) {
2981                // custom genre string
2982                buffer[size] = '\0';
2983
2984                mFileMetaData.setCString(
2985                        metadataKey, (const char *)buffer + 8);
2986            }
2987        } else {
2988            buffer[size] = '\0';
2989
2990            mFileMetaData.setCString(
2991                    metadataKey, (const char *)buffer + 8);
2992        }
2993    }
2994
2995    delete[] buffer;
2996    buffer = NULL;
2997
2998    return OK;
2999}
3000
3001status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
3002    if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
3003        return ERROR_MALFORMED;
3004    }
3005
3006    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
3007    if (buffer == NULL) {
3008        return ERROR_MALFORMED;
3009    }
3010    if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
3011        delete[] buffer;
3012        buffer = NULL;
3013
3014        return ERROR_IO;
3015    }
3016
3017    int32_t type = U32_AT(&buffer[0]);
3018    if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
3019            || (type == FOURCC('n', 'c', 'l', 'c') && size >= 10)) {
3020        int32_t primaries = U16_AT(&buffer[4]);
3021        int32_t transfer = U16_AT(&buffer[6]);
3022        int32_t coeffs = U16_AT(&buffer[8]);
3023        bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);
3024
3025        ColorAspects aspects;
3026        ColorUtils::convertIsoColorAspectsToCodecAspects(
3027                primaries, transfer, coeffs, fullRange, aspects);
3028
3029        // only store the first color specification
3030        if (!mLastTrack->meta.hasData(kKeyColorPrimaries)) {
3031            mLastTrack->meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries);
3032            mLastTrack->meta.setInt32(kKeyTransferFunction, aspects.mTransfer);
3033            mLastTrack->meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
3034            mLastTrack->meta.setInt32(kKeyColorRange, aspects.mRange);
3035        }
3036    }
3037
3038    delete[] buffer;
3039    buffer = NULL;
3040
3041    return OK;
3042}
3043
3044status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
3045    if (size < 4 || size == SIZE_MAX) {
3046        return ERROR_MALFORMED;
3047    }
3048
3049    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
3050    if (buffer == NULL) {
3051        return ERROR_MALFORMED;
3052    }
3053    if (mDataSource->readAt(
3054                offset, buffer, size) != (ssize_t)size) {
3055        delete[] buffer;
3056        buffer = NULL;
3057
3058        return ERROR_IO;
3059    }
3060
3061    uint32_t metadataKey = 0;
3062    switch (mPath[depth]) {
3063        case FOURCC('t', 'i', 't', 'l'):
3064        {
3065            metadataKey = kKeyTitle;
3066            break;
3067        }
3068        case FOURCC('p', 'e', 'r', 'f'):
3069        {
3070            metadataKey = kKeyArtist;
3071            break;
3072        }
3073        case FOURCC('a', 'u', 't', 'h'):
3074        {
3075            metadataKey = kKeyWriter;
3076            break;
3077        }
3078        case FOURCC('g', 'n', 'r', 'e'):
3079        {
3080            metadataKey = kKeyGenre;
3081            break;
3082        }
3083        case FOURCC('a', 'l', 'b', 'm'):
3084        {
3085            if (buffer[size - 1] != '\0') {
3086              char tmp[4];
3087              sprintf(tmp, "%u", buffer[size - 1]);
3088
3089              mFileMetaData.setCString(kKeyCDTrackNumber, tmp);
3090            }
3091
3092            metadataKey = kKeyAlbum;
3093            break;
3094        }
3095        case FOURCC('y', 'r', 'r', 'c'):
3096        {
3097            if (size < 6) {
3098                delete[] buffer;
3099                buffer = NULL;
3100                ALOGE("b/62133227");
3101                android_errorWriteLog(0x534e4554, "62133227");
3102                return ERROR_MALFORMED;
3103            }
3104            char tmp[5];
3105            uint16_t year = U16_AT(&buffer[4]);
3106
3107            if (year < 10000) {
3108                sprintf(tmp, "%u", year);
3109
3110                mFileMetaData.setCString(kKeyYear, tmp);
3111            }
3112            break;
3113        }
3114
3115        default:
3116            break;
3117    }
3118
3119    if (metadataKey > 0) {
3120        bool isUTF8 = true; // Common case
3121        char16_t *framedata = NULL;
3122        int len16 = 0; // Number of UTF-16 characters
3123
3124        // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
3125        if (size < 6) {
3126            delete[] buffer;
3127            buffer = NULL;
3128            return ERROR_MALFORMED;
3129        }
3130
3131        if (size - 6 >= 4) {
3132            len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
3133            framedata = (char16_t *)(buffer + 6);
3134            if (0xfffe == *framedata) {
3135                // endianness marker (BOM) doesn't match host endianness
3136                for (int i = 0; i < len16; i++) {
3137                    framedata[i] = bswap_16(framedata[i]);
3138                }
3139                // BOM is now swapped to 0xfeff, we will execute next block too
3140            }
3141
3142            if (0xfeff == *framedata) {
3143                // Remove the BOM
3144                framedata++;
3145                len16--;
3146                isUTF8 = false;
3147            }
3148            // else normal non-zero-length UTF-8 string
3149            // we can't handle UTF-16 without BOM as there is no other
3150            // indication of encoding.
3151        }
3152
3153        if (isUTF8) {
3154            buffer[size] = 0;
3155            mFileMetaData.setCString(metadataKey, (const char *)buffer + 6);
3156        } else {
3157            // Convert from UTF-16 string to UTF-8 string.
3158            String8 tmpUTF8str(framedata, len16);
3159            mFileMetaData.setCString(metadataKey, tmpUTF8str.string());
3160        }
3161    }
3162
3163    delete[] buffer;
3164    buffer = NULL;
3165
3166    return OK;
3167}
3168
3169void MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
3170    ID3 id3(mDataSource, true /* ignorev1 */, offset);
3171
3172    if (id3.isValid()) {
3173        struct Map {
3174            int key;
3175            const char *tag1;
3176            const char *tag2;
3177        };
3178        static const Map kMap[] = {
3179            { kKeyAlbum, "TALB", "TAL" },
3180            { kKeyArtist, "TPE1", "TP1" },
3181            { kKeyAlbumArtist, "TPE2", "TP2" },
3182            { kKeyComposer, "TCOM", "TCM" },
3183            { kKeyGenre, "TCON", "TCO" },
3184            { kKeyTitle, "TIT2", "TT2" },
3185            { kKeyYear, "TYE", "TYER" },
3186            { kKeyAuthor, "TXT", "TEXT" },
3187            { kKeyCDTrackNumber, "TRK", "TRCK" },
3188            { kKeyDiscNumber, "TPA", "TPOS" },
3189            { kKeyCompilation, "TCP", "TCMP" },
3190        };
3191        static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
3192
3193        for (size_t i = 0; i < kNumMapEntries; ++i) {
3194            if (!mFileMetaData.hasData(kMap[i].key)) {
3195                ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
3196                if (it->done()) {
3197                    delete it;
3198                    it = new ID3::Iterator(id3, kMap[i].tag2);
3199                }
3200
3201                if (it->done()) {
3202                    delete it;
3203                    continue;
3204                }
3205
3206                String8 s;
3207                it->getString(&s);
3208                delete it;
3209
3210                mFileMetaData.setCString(kMap[i].key, s);
3211            }
3212        }
3213
3214        size_t dataSize;
3215        String8 mime;
3216        const void *data = id3.getAlbumArt(&dataSize, &mime);
3217
3218        if (data) {
3219            mFileMetaData.setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
3220            mFileMetaData.setCString(kKeyAlbumArtMIME, mime.string());
3221        }
3222    }
3223}
3224
3225MediaTrack *MPEG4Extractor::getTrack(size_t index) {
3226    status_t err;
3227    if ((err = readMetaData()) != OK) {
3228        return NULL;
3229    }
3230
3231    Track *track = mFirstTrack;
3232    while (index > 0) {
3233        if (track == NULL) {
3234            return NULL;
3235        }
3236
3237        track = track->next;
3238        --index;
3239    }
3240
3241    if (track == NULL) {
3242        return NULL;
3243    }
3244
3245
3246    Trex *trex = NULL;
3247    int32_t trackId;
3248    if (track->meta.findInt32(kKeyTrackID, &trackId)) {
3249        for (size_t i = 0; i < mTrex.size(); i++) {
3250            Trex *t = &mTrex.editItemAt(i);
3251            if (t->track_ID == (uint32_t) trackId) {
3252                trex = t;
3253                break;
3254            }
3255        }
3256    } else {
3257        ALOGE("b/21657957");
3258        return NULL;
3259    }
3260
3261    ALOGV("getTrack called, pssh: %zu", mPssh.size());
3262
3263    const char *mime;
3264    if (!track->meta.findCString(kKeyMIMEType, &mime)) {
3265        return NULL;
3266    }
3267
3268    sp<ItemTable> itemTable;
3269    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3270        uint32_t type;
3271        const void *data;
3272        size_t size;
3273        if (!track->meta.findData(kKeyAVCC, &type, &data, &size)) {
3274            return NULL;
3275        }
3276
3277        const uint8_t *ptr = (const uint8_t *)data;
3278
3279        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
3280            return NULL;
3281        }
3282    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)
3283            || !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
3284        uint32_t type;
3285        const void *data;
3286        size_t size;
3287        if (!track->meta.findData(kKeyHVCC, &type, &data, &size)) {
3288            return NULL;
3289        }
3290
3291        const uint8_t *ptr = (const uint8_t *)data;
3292
3293        if (size < 22 || ptr[0] != 1) {  // configurationVersion == 1
3294            return NULL;
3295        }
3296        if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
3297            itemTable = mItemTable;
3298        }
3299    }
3300
3301    MPEG4Source *source =  new MPEG4Source(
3302            track->meta, mDataSource, track->timescale, track->sampleTable,
3303            mSidxEntries, trex, mMoofOffset, itemTable);
3304    if (source->init() != OK) {
3305        delete source;
3306        return NULL;
3307    }
3308    return source;
3309}
3310
3311// static
3312status_t MPEG4Extractor::verifyTrack(Track *track) {
3313    const char *mime;
3314    CHECK(track->meta.findCString(kKeyMIMEType, &mime));
3315
3316    uint32_t type;
3317    const void *data;
3318    size_t size;
3319    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3320        if (!track->meta.findData(kKeyAVCC, &type, &data, &size)
3321                || type != kTypeAVCC) {
3322            return ERROR_MALFORMED;
3323        }
3324    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
3325        if (!track->meta.findData(kKeyHVCC, &type, &data, &size)
3326                    || type != kTypeHVCC) {
3327            return ERROR_MALFORMED;
3328        }
3329    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
3330            || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
3331            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
3332        if (!track->meta.findData(kKeyESDS, &type, &data, &size)
3333                || type != kTypeESDS) {
3334            return ERROR_MALFORMED;
3335        }
3336    }
3337
3338    if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
3339        // Make sure we have all the metadata we need.
3340        ALOGE("stbl atom missing/invalid.");
3341        return ERROR_MALFORMED;
3342    }
3343
3344    if (track->timescale == 0) {
3345        ALOGE("timescale invalid.");
3346        return ERROR_MALFORMED;
3347    }
3348
3349    return OK;
3350}
3351
3352typedef enum {
3353    //AOT_NONE             = -1,
3354    //AOT_NULL_OBJECT      = 0,
3355    //AOT_AAC_MAIN         = 1, /**< Main profile                              */
3356    AOT_AAC_LC           = 2,   /**< Low Complexity object                     */
3357    //AOT_AAC_SSR          = 3,
3358    //AOT_AAC_LTP          = 4,
3359    AOT_SBR              = 5,
3360    //AOT_AAC_SCAL         = 6,
3361    //AOT_TWIN_VQ          = 7,
3362    //AOT_CELP             = 8,
3363    //AOT_HVXC             = 9,
3364    //AOT_RSVD_10          = 10, /**< (reserved)                                */
3365    //AOT_RSVD_11          = 11, /**< (reserved)                                */
3366    //AOT_TTSI             = 12, /**< TTSI Object                               */
3367    //AOT_MAIN_SYNTH       = 13, /**< Main Synthetic object                     */
3368    //AOT_WAV_TAB_SYNTH    = 14, /**< Wavetable Synthesis object                */
3369    //AOT_GEN_MIDI         = 15, /**< General MIDI object                       */
3370    //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
3371    AOT_ER_AAC_LC        = 17,   /**< Error Resilient(ER) AAC Low Complexity    */
3372    //AOT_RSVD_18          = 18, /**< (reserved)                                */
3373    //AOT_ER_AAC_LTP       = 19, /**< Error Resilient(ER) AAC LTP object        */
3374    AOT_ER_AAC_SCAL      = 20,   /**< Error Resilient(ER) AAC Scalable object   */
3375    //AOT_ER_TWIN_VQ       = 21, /**< Error Resilient(ER) TwinVQ object         */
3376    AOT_ER_BSAC          = 22,   /**< Error Resilient(ER) BSAC object           */
3377    AOT_ER_AAC_LD        = 23,   /**< Error Resilient(ER) AAC LowDelay object   */
3378    //AOT_ER_CELP          = 24, /**< Error Resilient(ER) CELP object           */
3379    //AOT_ER_HVXC          = 25, /**< Error Resilient(ER) HVXC object           */
3380    //AOT_ER_HILN          = 26, /**< Error Resilient(ER) HILN object           */
3381    //AOT_ER_PARA          = 27, /**< Error Resilient(ER) Parametric object     */
3382    //AOT_RSVD_28          = 28, /**< might become SSC                          */
3383    AOT_PS               = 29,   /**< PS, Parametric Stereo (includes SBR)      */
3384    //AOT_MPEGS            = 30, /**< MPEG Surround                             */
3385
3386    AOT_ESCAPE           = 31,   /**< Signal AOT uses more than 5 bits          */
3387
3388    //AOT_MP3ONMP4_L1      = 32, /**< MPEG-Layer1 in mp4                        */
3389    //AOT_MP3ONMP4_L2      = 33, /**< MPEG-Layer2 in mp4                        */
3390    //AOT_MP3ONMP4_L3      = 34, /**< MPEG-Layer3 in mp4                        */
3391    //AOT_RSVD_35          = 35, /**< might become DST                          */
3392    //AOT_RSVD_36          = 36, /**< might become ALS                          */
3393    //AOT_AAC_SLS          = 37, /**< AAC + SLS                                 */
3394    //AOT_SLS              = 38, /**< SLS                                       */
3395    //AOT_ER_AAC_ELD       = 39, /**< AAC Enhanced Low Delay                    */
3396
3397    //AOT_USAC             = 42, /**< USAC                                      */
3398    //AOT_SAOC             = 43, /**< SAOC                                      */
3399    //AOT_LD_MPEGS         = 44, /**< Low Delay MPEG Surround                   */
3400
3401    //AOT_RSVD50           = 50,  /**< Interim AOT for Rsvd50                   */
3402} AUDIO_OBJECT_TYPE;
3403
3404status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
3405        const void *esds_data, size_t esds_size) {
3406    ESDS esds(esds_data, esds_size);
3407
3408    uint8_t objectTypeIndication;
3409    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
3410        return ERROR_MALFORMED;
3411    }
3412
3413    if (objectTypeIndication == 0xe1) {
3414        // This isn't MPEG4 audio at all, it's QCELP 14k...
3415        if (mLastTrack == NULL)
3416            return ERROR_MALFORMED;
3417
3418        mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
3419        return OK;
3420    }
3421
3422    if (objectTypeIndication  == 0x6b) {
3423        // The media subtype is MP3 audio
3424        // Our software MP3 audio decoder may not be able to handle
3425        // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
3426        ALOGE("MP3 track in MP4/3GPP file is not supported");
3427        return ERROR_UNSUPPORTED;
3428    }
3429
3430    if (mLastTrack != NULL) {
3431        uint32_t maxBitrate = 0;
3432        uint32_t avgBitrate = 0;
3433        esds.getBitRate(&maxBitrate, &avgBitrate);
3434        if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
3435            mLastTrack->meta.setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
3436        }
3437        if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
3438            mLastTrack->meta.setInt32(kKeyBitRate, (int32_t)avgBitrate);
3439        }
3440    }
3441
3442    const uint8_t *csd;
3443    size_t csd_size;
3444    if (esds.getCodecSpecificInfo(
3445                (const void **)&csd, &csd_size) != OK) {
3446        return ERROR_MALFORMED;
3447    }
3448
3449    if (kUseHexDump) {
3450        printf("ESD of size %zu\n", csd_size);
3451        hexdump(csd, csd_size);
3452    }
3453
3454    if (csd_size == 0) {
3455        // There's no further information, i.e. no codec specific data
3456        // Let's assume that the information provided in the mpeg4 headers
3457        // is accurate and hope for the best.
3458
3459        return OK;
3460    }
3461
3462    if (csd_size < 2) {
3463        return ERROR_MALFORMED;
3464    }
3465
3466    static uint32_t kSamplingRate[] = {
3467        96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
3468        16000, 12000, 11025, 8000, 7350
3469    };
3470
3471    ABitReader br(csd, csd_size);
3472    uint32_t objectType = br.getBits(5);
3473
3474    if (objectType == 31) {  // AAC-ELD => additional 6 bits
3475        objectType = 32 + br.getBits(6);
3476    }
3477
3478    if (mLastTrack == NULL)
3479        return ERROR_MALFORMED;
3480
3481    //keep AOT type
3482    mLastTrack->meta.setInt32(kKeyAACAOT, objectType);
3483
3484    uint32_t freqIndex = br.getBits(4);
3485
3486    int32_t sampleRate = 0;
3487    int32_t numChannels = 0;
3488    if (freqIndex == 15) {
3489        if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
3490        sampleRate = br.getBits(24);
3491        numChannels = br.getBits(4);
3492    } else {
3493        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3494        numChannels = br.getBits(4);
3495
3496        if (freqIndex == 13 || freqIndex == 14) {
3497            return ERROR_MALFORMED;
3498        }
3499
3500        sampleRate = kSamplingRate[freqIndex];
3501    }
3502
3503    if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
3504        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3505        uint32_t extFreqIndex = br.getBits(4);
3506        int32_t extSampleRate __unused;
3507        if (extFreqIndex == 15) {
3508            if (csd_size < 8) {
3509                return ERROR_MALFORMED;
3510            }
3511            if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
3512            extSampleRate = br.getBits(24);
3513        } else {
3514            if (extFreqIndex == 13 || extFreqIndex == 14) {
3515                return ERROR_MALFORMED;
3516            }
3517            extSampleRate = kSamplingRate[extFreqIndex];
3518        }
3519        //TODO: save the extension sampling rate value in meta data =>
3520        //      mLastTrack->meta.setInt32(kKeyExtSampleRate, extSampleRate);
3521    }
3522
3523    switch (numChannels) {
3524        // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
3525        case 0:
3526        case 1:// FC
3527        case 2:// FL FR
3528        case 3:// FC, FL FR
3529        case 4:// FC, FL FR, RC
3530        case 5:// FC, FL FR, SL SR
3531        case 6:// FC, FL FR, SL SR, LFE
3532            //numChannels already contains the right value
3533            break;
3534        case 11:// FC, FL FR, SL SR, RC, LFE
3535            numChannels = 7;
3536            break;
3537        case 7: // FC, FCL FCR, FL FR, SL SR, LFE
3538        case 12:// FC, FL  FR,  SL SR, RL RR, LFE
3539        case 14:// FC, FL  FR,  SL SR, LFE, FHL FHR
3540            numChannels = 8;
3541            break;
3542        default:
3543            return ERROR_UNSUPPORTED;
3544    }
3545
3546    {
3547        if (objectType == AOT_SBR || objectType == AOT_PS) {
3548            if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3549            objectType = br.getBits(5);
3550
3551            if (objectType == AOT_ESCAPE) {
3552                if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
3553                objectType = 32 + br.getBits(6);
3554            }
3555        }
3556        if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
3557                objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
3558                objectType == AOT_ER_BSAC) {
3559            if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
3560            const int32_t frameLengthFlag __unused = br.getBits(1);
3561
3562            const int32_t dependsOnCoreCoder = br.getBits(1);
3563
3564            if (dependsOnCoreCoder ) {
3565                if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
3566                const int32_t coreCoderDelay __unused = br.getBits(14);
3567            }
3568
3569            int32_t extensionFlag = -1;
3570            if (br.numBitsLeft() > 0) {
3571                extensionFlag = br.getBits(1);
3572            } else {
3573                switch (objectType) {
3574                // 14496-3 4.5.1.1 extensionFlag
3575                case AOT_AAC_LC:
3576                    extensionFlag = 0;
3577                    break;
3578                case AOT_ER_AAC_LC:
3579                case AOT_ER_AAC_SCAL:
3580                case AOT_ER_BSAC:
3581                case AOT_ER_AAC_LD:
3582                    extensionFlag = 1;
3583                    break;
3584                default:
3585                    return ERROR_MALFORMED;
3586                    break;
3587                }
3588                ALOGW("csd missing extension flag; assuming %d for object type %u.",
3589                        extensionFlag, objectType);
3590            }
3591
3592            if (numChannels == 0) {
3593                int32_t channelsEffectiveNum = 0;
3594                int32_t channelsNum = 0;
3595                if (br.numBitsLeft() < 32) {
3596                    return ERROR_MALFORMED;
3597                }
3598                const int32_t ElementInstanceTag __unused = br.getBits(4);
3599                const int32_t Profile __unused = br.getBits(2);
3600                const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
3601                const int32_t NumFrontChannelElements = br.getBits(4);
3602                const int32_t NumSideChannelElements = br.getBits(4);
3603                const int32_t NumBackChannelElements = br.getBits(4);
3604                const int32_t NumLfeChannelElements = br.getBits(2);
3605                const int32_t NumAssocDataElements __unused = br.getBits(3);
3606                const int32_t NumValidCcElements __unused = br.getBits(4);
3607
3608                const int32_t MonoMixdownPresent = br.getBits(1);
3609
3610                if (MonoMixdownPresent != 0) {
3611                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3612                    const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
3613                }
3614
3615                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3616                const int32_t StereoMixdownPresent = br.getBits(1);
3617                if (StereoMixdownPresent != 0) {
3618                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3619                    const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
3620                }
3621
3622                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3623                const int32_t MatrixMixdownIndexPresent = br.getBits(1);
3624                if (MatrixMixdownIndexPresent != 0) {
3625                    if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
3626                    const int32_t MatrixMixdownIndex __unused = br.getBits(2);
3627                    const int32_t PseudoSurroundEnable __unused = br.getBits(1);
3628                }
3629
3630                int i;
3631                for (i=0; i < NumFrontChannelElements; i++) {
3632                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3633                    const int32_t FrontElementIsCpe = br.getBits(1);
3634                    const int32_t FrontElementTagSelect __unused = br.getBits(4);
3635                    channelsNum += FrontElementIsCpe ? 2 : 1;
3636                }
3637
3638                for (i=0; i < NumSideChannelElements; i++) {
3639                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3640                    const int32_t SideElementIsCpe = br.getBits(1);
3641                    const int32_t SideElementTagSelect __unused = br.getBits(4);
3642                    channelsNum += SideElementIsCpe ? 2 : 1;
3643                }
3644
3645                for (i=0; i < NumBackChannelElements; i++) {
3646                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3647                    const int32_t BackElementIsCpe = br.getBits(1);
3648                    const int32_t BackElementTagSelect __unused = br.getBits(4);
3649                    channelsNum += BackElementIsCpe ? 2 : 1;
3650                }
3651                channelsEffectiveNum = channelsNum;
3652
3653                for (i=0; i < NumLfeChannelElements; i++) {
3654                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3655                    const int32_t LfeElementTagSelect __unused = br.getBits(4);
3656                    channelsNum += 1;
3657                }
3658                ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
3659                ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
3660                numChannels = channelsNum;
3661            }
3662        }
3663    }
3664
3665    if (numChannels == 0) {
3666        return ERROR_UNSUPPORTED;
3667    }
3668
3669    if (mLastTrack == NULL)
3670        return ERROR_MALFORMED;
3671
3672    int32_t prevSampleRate;
3673    CHECK(mLastTrack->meta.findInt32(kKeySampleRate, &prevSampleRate));
3674
3675    if (prevSampleRate != sampleRate) {
3676        ALOGV("mpeg4 audio sample rate different from previous setting. "
3677             "was: %d, now: %d", prevSampleRate, sampleRate);
3678    }
3679
3680    mLastTrack->meta.setInt32(kKeySampleRate, sampleRate);
3681
3682    int32_t prevChannelCount;
3683    CHECK(mLastTrack->meta.findInt32(kKeyChannelCount, &prevChannelCount));
3684
3685    if (prevChannelCount != numChannels) {
3686        ALOGV("mpeg4 audio channel count different from previous setting. "
3687             "was: %d, now: %d", prevChannelCount, numChannels);
3688    }
3689
3690    mLastTrack->meta.setInt32(kKeyChannelCount, numChannels);
3691
3692    return OK;
3693}
3694
3695////////////////////////////////////////////////////////////////////////////////
3696
3697MPEG4Source::MPEG4Source(
3698        MetaDataBase &format,
3699        DataSourceBase *dataSource,
3700        int32_t timeScale,
3701        const sp<SampleTable> &sampleTable,
3702        Vector<SidxEntry> &sidx,
3703        const Trex *trex,
3704        off64_t firstMoofOffset,
3705        const sp<ItemTable> &itemTable)
3706    : mFormat(format),
3707      mDataSource(dataSource),
3708      mTimescale(timeScale),
3709      mSampleTable(sampleTable),
3710      mCurrentSampleIndex(0),
3711      mCurrentFragmentIndex(0),
3712      mSegments(sidx),
3713      mTrex(trex),
3714      mFirstMoofOffset(firstMoofOffset),
3715      mCurrentMoofOffset(firstMoofOffset),
3716      mNextMoofOffset(-1),
3717      mCurrentTime(0),
3718      mCurrentSampleInfoAllocSize(0),
3719      mCurrentSampleInfoSizes(NULL),
3720      mCurrentSampleInfoOffsetsAllocSize(0),
3721      mCurrentSampleInfoOffsets(NULL),
3722      mIsAVC(false),
3723      mIsHEVC(false),
3724      mNALLengthSize(0),
3725      mStarted(false),
3726      mGroup(NULL),
3727      mBuffer(NULL),
3728      mWantsNALFragments(false),
3729      mSrcBuffer(NULL),
3730      mIsHeif(itemTable != NULL),
3731      mItemTable(itemTable) {
3732
3733    memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
3734
3735    mFormat.findInt32(kKeyCryptoMode, &mCryptoMode);
3736    mDefaultIVSize = 0;
3737    mFormat.findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
3738    uint32_t keytype;
3739    const void *key;
3740    size_t keysize;
3741    if (mFormat.findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
3742        CHECK(keysize <= 16);
3743        memset(mCryptoKey, 0, 16);
3744        memcpy(mCryptoKey, key, keysize);
3745    }
3746
3747    const char *mime;
3748    bool success = mFormat.findCString(kKeyMIMEType, &mime);
3749    CHECK(success);
3750
3751    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
3752    mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC) ||
3753              !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
3754
3755    if (mIsAVC) {
3756        uint32_t type;
3757        const void *data;
3758        size_t size;
3759        CHECK(format.findData(kKeyAVCC, &type, &data, &size));
3760
3761        const uint8_t *ptr = (const uint8_t *)data;
3762
3763        CHECK(size >= 7);
3764        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
3765
3766        // The number of bytes used to encode the length of a NAL unit.
3767        mNALLengthSize = 1 + (ptr[4] & 3);
3768    } else if (mIsHEVC) {
3769        uint32_t type;
3770        const void *data;
3771        size_t size;
3772        CHECK(format.findData(kKeyHVCC, &type, &data, &size));
3773
3774        const uint8_t *ptr = (const uint8_t *)data;
3775
3776        CHECK(size >= 22);
3777        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
3778
3779        mNALLengthSize = 1 + (ptr[14 + 7] & 3);
3780    }
3781
3782    CHECK(format.findInt32(kKeyTrackID, &mTrackId));
3783
3784}
3785
3786status_t MPEG4Source::init() {
3787    if (mFirstMoofOffset != 0) {
3788        off64_t offset = mFirstMoofOffset;
3789        return parseChunk(&offset);
3790    }
3791    return OK;
3792}
3793
3794MPEG4Source::~MPEG4Source() {
3795    if (mStarted) {
3796        stop();
3797    }
3798    free(mCurrentSampleInfoSizes);
3799    free(mCurrentSampleInfoOffsets);
3800}
3801
3802status_t MPEG4Source::start(MetaDataBase *params) {
3803    Mutex::Autolock autoLock(mLock);
3804
3805    CHECK(!mStarted);
3806
3807    int32_t val;
3808    if (params && params->findInt32(kKeyWantsNALFragments, &val)
3809        && val != 0) {
3810        mWantsNALFragments = true;
3811    } else {
3812        mWantsNALFragments = false;
3813    }
3814
3815    int32_t tmp;
3816    CHECK(mFormat.findInt32(kKeyMaxInputSize, &tmp));
3817    size_t max_size = tmp;
3818
3819    // A somewhat arbitrary limit that should be sufficient for 8k video frames
3820    // If you see the message below for a valid input stream: increase the limit
3821    const size_t kMaxBufferSize = 64 * 1024 * 1024;
3822    if (max_size > kMaxBufferSize) {
3823        ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize);
3824        return ERROR_MALFORMED;
3825    }
3826    if (max_size == 0) {
3827        ALOGE("zero max input size");
3828        return ERROR_MALFORMED;
3829    }
3830
3831    // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize.
3832    const size_t kMaxBuffers = 8;
3833    const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers);
3834    mGroup = new MediaBufferGroup(buffers, max_size);
3835    mSrcBuffer = new (std::nothrow) uint8_t[max_size];
3836    if (mSrcBuffer == NULL) {
3837        // file probably specified a bad max size
3838        delete mGroup;
3839        mGroup = NULL;
3840        return ERROR_MALFORMED;
3841    }
3842
3843    mStarted = true;
3844
3845    return OK;
3846}
3847
3848status_t MPEG4Source::stop() {
3849    Mutex::Autolock autoLock(mLock);
3850
3851    CHECK(mStarted);
3852
3853    if (mBuffer != NULL) {
3854        mBuffer->release();
3855        mBuffer = NULL;
3856    }
3857
3858    delete[] mSrcBuffer;
3859    mSrcBuffer = NULL;
3860
3861    delete mGroup;
3862    mGroup = NULL;
3863
3864    mStarted = false;
3865    mCurrentSampleIndex = 0;
3866
3867    return OK;
3868}
3869
3870status_t MPEG4Source::parseChunk(off64_t *offset) {
3871    uint32_t hdr[2];
3872    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
3873        return ERROR_IO;
3874    }
3875    uint64_t chunk_size = ntohl(hdr[0]);
3876    uint32_t chunk_type = ntohl(hdr[1]);
3877    off64_t data_offset = *offset + 8;
3878
3879    if (chunk_size == 1) {
3880        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
3881            return ERROR_IO;
3882        }
3883        chunk_size = ntoh64(chunk_size);
3884        data_offset += 8;
3885
3886        if (chunk_size < 16) {
3887            // The smallest valid chunk is 16 bytes long in this case.
3888            return ERROR_MALFORMED;
3889        }
3890    } else if (chunk_size < 8) {
3891        // The smallest valid chunk is 8 bytes long.
3892        return ERROR_MALFORMED;
3893    }
3894
3895    char chunk[5];
3896    MakeFourCCString(chunk_type, chunk);
3897    ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
3898
3899    off64_t chunk_data_size = *offset + chunk_size - data_offset;
3900
3901    switch(chunk_type) {
3902
3903        case FOURCC('t', 'r', 'a', 'f'):
3904        case FOURCC('m', 'o', 'o', 'f'): {
3905            off64_t stop_offset = *offset + chunk_size;
3906            *offset = data_offset;
3907            while (*offset < stop_offset) {
3908                status_t err = parseChunk(offset);
3909                if (err != OK) {
3910                    return err;
3911                }
3912            }
3913            if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
3914                // *offset points to the box following this moof. Find the next moof from there.
3915
3916                while (true) {
3917                    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
3918                        // no more box to the end of file.
3919                        break;
3920                    }
3921                    chunk_size = ntohl(hdr[0]);
3922                    chunk_type = ntohl(hdr[1]);
3923                    if (chunk_size == 1) {
3924                        // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box
3925                        // which is defined in 4.2 Object Structure.
3926                        // When chunk_size==1, 8 bytes follows as "largesize".
3927                        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
3928                            return ERROR_IO;
3929                        }
3930                        chunk_size = ntoh64(chunk_size);
3931                        if (chunk_size < 16) {
3932                            // The smallest valid chunk is 16 bytes long in this case.
3933                            return ERROR_MALFORMED;
3934                        }
3935                    } else if (chunk_size == 0) {
3936                        // next box extends to end of file.
3937                    } else if (chunk_size < 8) {
3938                        // The smallest valid chunk is 8 bytes long in this case.
3939                        return ERROR_MALFORMED;
3940                    }
3941
3942                    if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
3943                        mNextMoofOffset = *offset;
3944                        break;
3945                    } else if (chunk_size == 0) {
3946                        break;
3947                    }
3948                    *offset += chunk_size;
3949                }
3950            }
3951            break;
3952        }
3953
3954        case FOURCC('t', 'f', 'h', 'd'): {
3955                status_t err;
3956                if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
3957                    return err;
3958                }
3959                *offset += chunk_size;
3960                break;
3961        }
3962
3963        case FOURCC('t', 'r', 'u', 'n'): {
3964                status_t err;
3965                if (mLastParsedTrackId == mTrackId) {
3966                    if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
3967                        return err;
3968                    }
3969                }
3970
3971                *offset += chunk_size;
3972                break;
3973        }
3974
3975        case FOURCC('s', 'a', 'i', 'z'): {
3976            status_t err;
3977            if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
3978                return err;
3979            }
3980            *offset += chunk_size;
3981            break;
3982        }
3983        case FOURCC('s', 'a', 'i', 'o'): {
3984            status_t err;
3985            if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
3986                return err;
3987            }
3988            *offset += chunk_size;
3989            break;
3990        }
3991
3992        case FOURCC('m', 'd', 'a', 't'): {
3993            // parse DRM info if present
3994            ALOGV("MPEG4Source::parseChunk mdat");
3995            // if saiz/saoi was previously observed, do something with the sampleinfos
3996            *offset += chunk_size;
3997            break;
3998        }
3999
4000        default: {
4001            *offset += chunk_size;
4002            break;
4003        }
4004    }
4005    return OK;
4006}
4007
4008status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
4009        off64_t offset, off64_t /* size */) {
4010    ALOGV("parseSampleAuxiliaryInformationSizes");
4011    // 14496-12 8.7.12
4012    uint8_t version;
4013    if (mDataSource->readAt(
4014            offset, &version, sizeof(version))
4015            < (ssize_t)sizeof(version)) {
4016        return ERROR_IO;
4017    }
4018
4019    if (version != 0) {
4020        return ERROR_UNSUPPORTED;
4021    }
4022    offset++;
4023
4024    uint32_t flags;
4025    if (!mDataSource->getUInt24(offset, &flags)) {
4026        return ERROR_IO;
4027    }
4028    offset += 3;
4029
4030    if (flags & 1) {
4031        uint32_t tmp;
4032        if (!mDataSource->getUInt32(offset, &tmp)) {
4033            return ERROR_MALFORMED;
4034        }
4035        mCurrentAuxInfoType = tmp;
4036        offset += 4;
4037        if (!mDataSource->getUInt32(offset, &tmp)) {
4038            return ERROR_MALFORMED;
4039        }
4040        mCurrentAuxInfoTypeParameter = tmp;
4041        offset += 4;
4042    }
4043
4044    uint8_t defsize;
4045    if (mDataSource->readAt(offset, &defsize, 1) != 1) {
4046        return ERROR_MALFORMED;
4047    }
4048    mCurrentDefaultSampleInfoSize = defsize;
4049    offset++;
4050
4051    uint32_t smplcnt;
4052    if (!mDataSource->getUInt32(offset, &smplcnt)) {
4053        return ERROR_MALFORMED;
4054    }
4055    mCurrentSampleInfoCount = smplcnt;
4056    offset += 4;
4057
4058    if (mCurrentDefaultSampleInfoSize != 0) {
4059        ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
4060        return OK;
4061    }
4062    if (smplcnt > mCurrentSampleInfoAllocSize) {
4063        uint8_t * newPtr =  (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
4064        if (newPtr == NULL) {
4065            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoAllocSize, smplcnt);
4066            return NO_MEMORY;
4067        }
4068        mCurrentSampleInfoSizes = newPtr;
4069        mCurrentSampleInfoAllocSize = smplcnt;
4070    }
4071
4072    mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
4073    return OK;
4074}
4075
4076status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
4077        off64_t offset, off64_t /* size */) {
4078    ALOGV("parseSampleAuxiliaryInformationOffsets");
4079    // 14496-12 8.7.13
4080    uint8_t version;
4081    if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
4082        return ERROR_IO;
4083    }
4084    offset++;
4085
4086    uint32_t flags;
4087    if (!mDataSource->getUInt24(offset, &flags)) {
4088        return ERROR_IO;
4089    }
4090    offset += 3;
4091
4092    uint32_t entrycount;
4093    if (!mDataSource->getUInt32(offset, &entrycount)) {
4094        return ERROR_IO;
4095    }
4096    offset += 4;
4097    if (entrycount == 0) {
4098        return OK;
4099    }
4100    if (entrycount > UINT32_MAX / 8) {
4101        return ERROR_MALFORMED;
4102    }
4103
4104    if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
4105        uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
4106        if (newPtr == NULL) {
4107            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
4108            return NO_MEMORY;
4109        }
4110        mCurrentSampleInfoOffsets = newPtr;
4111        mCurrentSampleInfoOffsetsAllocSize = entrycount;
4112    }
4113    mCurrentSampleInfoOffsetCount = entrycount;
4114
4115    if (mCurrentSampleInfoOffsets == NULL) {
4116        return OK;
4117    }
4118
4119    for (size_t i = 0; i < entrycount; i++) {
4120        if (version == 0) {
4121            uint32_t tmp;
4122            if (!mDataSource->getUInt32(offset, &tmp)) {
4123                return ERROR_IO;
4124            }
4125            mCurrentSampleInfoOffsets[i] = tmp;
4126            offset += 4;
4127        } else {
4128            uint64_t tmp;
4129            if (!mDataSource->getUInt64(offset, &tmp)) {
4130                return ERROR_IO;
4131            }
4132            mCurrentSampleInfoOffsets[i] = tmp;
4133            offset += 8;
4134        }
4135    }
4136
4137    // parse clear/encrypted data
4138
4139    off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
4140
4141    drmoffset += mCurrentMoofOffset;
4142    int ivlength;
4143    CHECK(mFormat.findInt32(kKeyCryptoDefaultIVSize, &ivlength));
4144
4145    // only 0, 8 and 16 byte initialization vectors are supported
4146    if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
4147        ALOGW("unsupported IV length: %d", ivlength);
4148        return ERROR_MALFORMED;
4149    }
4150    // read CencSampleAuxiliaryDataFormats
4151    for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
4152        if (i >= mCurrentSamples.size()) {
4153            ALOGW("too few samples");
4154            break;
4155        }
4156        Sample *smpl = &mCurrentSamples.editItemAt(i);
4157
4158        memset(smpl->iv, 0, 16);
4159        if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) {
4160            return ERROR_IO;
4161        }
4162
4163        drmoffset += ivlength;
4164
4165        int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
4166        if (smplinfosize == 0) {
4167            smplinfosize = mCurrentSampleInfoSizes[i];
4168        }
4169        if (smplinfosize > ivlength) {
4170            uint16_t numsubsamples;
4171            if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
4172                return ERROR_IO;
4173            }
4174            drmoffset += 2;
4175            for (size_t j = 0; j < numsubsamples; j++) {
4176                uint16_t numclear;
4177                uint32_t numencrypted;
4178                if (!mDataSource->getUInt16(drmoffset, &numclear)) {
4179                    return ERROR_IO;
4180                }
4181                drmoffset += 2;
4182                if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
4183                    return ERROR_IO;
4184                }
4185                drmoffset += 4;
4186                smpl->clearsizes.add(numclear);
4187                smpl->encryptedsizes.add(numencrypted);
4188            }
4189        } else {
4190            smpl->clearsizes.add(0);
4191            smpl->encryptedsizes.add(smpl->size);
4192        }
4193    }
4194
4195
4196    return OK;
4197}
4198
4199status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
4200
4201    if (size < 8) {
4202        return -EINVAL;
4203    }
4204
4205    uint32_t flags;
4206    if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
4207        return ERROR_MALFORMED;
4208    }
4209
4210    if (flags & 0xff000000) {
4211        return -EINVAL;
4212    }
4213
4214    if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
4215        return ERROR_MALFORMED;
4216    }
4217
4218    if (mLastParsedTrackId != mTrackId) {
4219        // this is not the right track, skip it
4220        return OK;
4221    }
4222
4223    mTrackFragmentHeaderInfo.mFlags = flags;
4224    mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
4225    offset += 8;
4226    size -= 8;
4227
4228    ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
4229
4230    if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
4231        if (size < 8) {
4232            return -EINVAL;
4233        }
4234
4235        if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
4236            return ERROR_MALFORMED;
4237        }
4238        offset += 8;
4239        size -= 8;
4240    }
4241
4242    if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
4243        if (size < 4) {
4244            return -EINVAL;
4245        }
4246
4247        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
4248            return ERROR_MALFORMED;
4249        }
4250        offset += 4;
4251        size -= 4;
4252    }
4253
4254    if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
4255        if (size < 4) {
4256            return -EINVAL;
4257        }
4258
4259        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
4260            return ERROR_MALFORMED;
4261        }
4262        offset += 4;
4263        size -= 4;
4264    }
4265
4266    if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
4267        if (size < 4) {
4268            return -EINVAL;
4269        }
4270
4271        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
4272            return ERROR_MALFORMED;
4273        }
4274        offset += 4;
4275        size -= 4;
4276    }
4277
4278    if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
4279        if (size < 4) {
4280            return -EINVAL;
4281        }
4282
4283        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
4284            return ERROR_MALFORMED;
4285        }
4286        offset += 4;
4287        size -= 4;
4288    }
4289
4290    if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
4291        mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
4292    }
4293
4294    mTrackFragmentHeaderInfo.mDataOffset = 0;
4295    return OK;
4296}
4297
4298status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
4299
4300    ALOGV("MPEG4Extractor::parseTrackFragmentRun");
4301    if (size < 8) {
4302        return -EINVAL;
4303    }
4304
4305    enum {
4306        kDataOffsetPresent                  = 0x01,
4307        kFirstSampleFlagsPresent            = 0x04,
4308        kSampleDurationPresent              = 0x100,
4309        kSampleSizePresent                  = 0x200,
4310        kSampleFlagsPresent                 = 0x400,
4311        kSampleCompositionTimeOffsetPresent = 0x800,
4312    };
4313
4314    uint32_t flags;
4315    if (!mDataSource->getUInt32(offset, &flags)) {
4316        return ERROR_MALFORMED;
4317    }
4318    // |version| only affects SampleCompositionTimeOffset field.
4319    // If version == 0, SampleCompositionTimeOffset is uint32_t;
4320    // Otherwise, SampleCompositionTimeOffset is int32_t.
4321    // Sample.compositionOffset is defined as int32_t.
4322    uint8_t version = flags >> 24;
4323    flags &= 0xffffff;
4324    ALOGV("fragment run version: 0x%02x, flags: 0x%06x", version, flags);
4325
4326    if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
4327        // These two shall not be used together.
4328        return -EINVAL;
4329    }
4330
4331    uint32_t sampleCount;
4332    if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
4333        return ERROR_MALFORMED;
4334    }
4335    offset += 8;
4336    size -= 8;
4337
4338    uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
4339
4340    uint32_t firstSampleFlags = 0;
4341
4342    if (flags & kDataOffsetPresent) {
4343        if (size < 4) {
4344            return -EINVAL;
4345        }
4346
4347        int32_t dataOffsetDelta;
4348        if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) {
4349            return ERROR_MALFORMED;
4350        }
4351
4352        dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
4353
4354        offset += 4;
4355        size -= 4;
4356    }
4357
4358    if (flags & kFirstSampleFlagsPresent) {
4359        if (size < 4) {
4360            return -EINVAL;
4361        }
4362
4363        if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
4364            return ERROR_MALFORMED;
4365        }
4366        offset += 4;
4367        size -= 4;
4368    }
4369
4370    uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
4371             sampleCtsOffset = 0;
4372
4373    size_t bytesPerSample = 0;
4374    if (flags & kSampleDurationPresent) {
4375        bytesPerSample += 4;
4376    } else if (mTrackFragmentHeaderInfo.mFlags
4377            & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
4378        sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
4379    } else if (mTrex) {
4380        sampleDuration = mTrex->default_sample_duration;
4381    }
4382
4383    if (flags & kSampleSizePresent) {
4384        bytesPerSample += 4;
4385    } else if (mTrackFragmentHeaderInfo.mFlags
4386            & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
4387        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
4388    } else {
4389        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
4390    }
4391
4392    if (flags & kSampleFlagsPresent) {
4393        bytesPerSample += 4;
4394    } else if (mTrackFragmentHeaderInfo.mFlags
4395            & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
4396        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
4397    } else {
4398        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
4399    }
4400
4401    if (flags & kSampleCompositionTimeOffsetPresent) {
4402        bytesPerSample += 4;
4403    } else {
4404        sampleCtsOffset = 0;
4405    }
4406
4407    if (size < (off64_t)(sampleCount * bytesPerSample)) {
4408        return -EINVAL;
4409    }
4410
4411    Sample tmp;
4412    for (uint32_t i = 0; i < sampleCount; ++i) {
4413        if (flags & kSampleDurationPresent) {
4414            if (!mDataSource->getUInt32(offset, &sampleDuration)) {
4415                return ERROR_MALFORMED;
4416            }
4417            offset += 4;
4418        }
4419
4420        if (flags & kSampleSizePresent) {
4421            if (!mDataSource->getUInt32(offset, &sampleSize)) {
4422                return ERROR_MALFORMED;
4423            }
4424            offset += 4;
4425        }
4426
4427        if (flags & kSampleFlagsPresent) {
4428            if (!mDataSource->getUInt32(offset, &sampleFlags)) {
4429                return ERROR_MALFORMED;
4430            }
4431            offset += 4;
4432        }
4433
4434        if (flags & kSampleCompositionTimeOffsetPresent) {
4435            if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
4436                return ERROR_MALFORMED;
4437            }
4438            offset += 4;
4439        }
4440
4441        ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
4442              " flags 0x%08x", i + 1,
4443                dataOffset, sampleSize, sampleDuration,
4444                (flags & kFirstSampleFlagsPresent) && i == 0
4445                    ? firstSampleFlags : sampleFlags);
4446        tmp.offset = dataOffset;
4447        tmp.size = sampleSize;
4448        tmp.duration = sampleDuration;
4449        tmp.compositionOffset = sampleCtsOffset;
4450        mCurrentSamples.add(tmp);
4451
4452        dataOffset += sampleSize;
4453    }
4454
4455    mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
4456
4457    return OK;
4458}
4459
4460status_t MPEG4Source::getFormat(MetaDataBase &meta) {
4461    Mutex::Autolock autoLock(mLock);
4462    meta = mFormat;
4463    return OK;
4464}
4465
4466size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
4467    switch (mNALLengthSize) {
4468        case 1:
4469            return *data;
4470        case 2:
4471            return U16_AT(data);
4472        case 3:
4473            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
4474        case 4:
4475            return U32_AT(data);
4476    }
4477
4478    // This cannot happen, mNALLengthSize springs to life by adding 1 to
4479    // a 2-bit integer.
4480    CHECK(!"Should not be here.");
4481
4482    return 0;
4483}
4484
4485status_t MPEG4Source::read(
4486        MediaBufferBase **out, const ReadOptions *options) {
4487    Mutex::Autolock autoLock(mLock);
4488
4489    CHECK(mStarted);
4490
4491    if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
4492        *out = nullptr;
4493        return WOULD_BLOCK;
4494    }
4495
4496    if (mFirstMoofOffset > 0) {
4497        return fragmentedRead(out, options);
4498    }
4499
4500    *out = NULL;
4501
4502    int64_t targetSampleTimeUs = -1;
4503
4504    int64_t seekTimeUs;
4505    ReadOptions::SeekMode mode;
4506    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4507        if (mIsHeif) {
4508            CHECK(mSampleTable == NULL);
4509            CHECK(mItemTable != NULL);
4510            int32_t imageIndex;
4511            if (!mFormat.findInt32(kKeyTrackID, &imageIndex)) {
4512                return ERROR_MALFORMED;
4513            }
4514
4515            status_t err;
4516            if (seekTimeUs >= 0) {
4517                err = mItemTable->findImageItem(imageIndex, &mCurrentSampleIndex);
4518            } else {
4519                err = mItemTable->findThumbnailItem(imageIndex, &mCurrentSampleIndex);
4520            }
4521            if (err != OK) {
4522                return err;
4523            }
4524        } else {
4525            uint32_t findFlags = 0;
4526            switch (mode) {
4527                case ReadOptions::SEEK_PREVIOUS_SYNC:
4528                    findFlags = SampleTable::kFlagBefore;
4529                    break;
4530                case ReadOptions::SEEK_NEXT_SYNC:
4531                    findFlags = SampleTable::kFlagAfter;
4532                    break;
4533                case ReadOptions::SEEK_CLOSEST_SYNC:
4534                case ReadOptions::SEEK_CLOSEST:
4535                    findFlags = SampleTable::kFlagClosest;
4536                    break;
4537                case ReadOptions::SEEK_FRAME_INDEX:
4538                    findFlags = SampleTable::kFlagFrameIndex;
4539                    break;
4540                default:
4541                    CHECK(!"Should not be here.");
4542                    break;
4543            }
4544
4545            uint32_t sampleIndex;
4546            status_t err = mSampleTable->findSampleAtTime(
4547                    seekTimeUs, 1000000, mTimescale,
4548                    &sampleIndex, findFlags);
4549
4550            if (mode == ReadOptions::SEEK_CLOSEST
4551                    || mode == ReadOptions::SEEK_FRAME_INDEX) {
4552                // We found the closest sample already, now we want the sync
4553                // sample preceding it (or the sample itself of course), even
4554                // if the subsequent sync sample is closer.
4555                findFlags = SampleTable::kFlagBefore;
4556            }
4557
4558            uint32_t syncSampleIndex;
4559            if (err == OK) {
4560                err = mSampleTable->findSyncSampleNear(
4561                        sampleIndex, &syncSampleIndex, findFlags);
4562            }
4563
4564            uint32_t sampleTime;
4565            if (err == OK) {
4566                err = mSampleTable->getMetaDataForSample(
4567                        sampleIndex, NULL, NULL, &sampleTime);
4568            }
4569
4570            if (err != OK) {
4571                if (err == ERROR_OUT_OF_RANGE) {
4572                    // An attempt to seek past the end of the stream would
4573                    // normally cause this ERROR_OUT_OF_RANGE error. Propagating
4574                    // this all the way to the MediaPlayer would cause abnormal
4575                    // termination. Legacy behaviour appears to be to behave as if
4576                    // we had seeked to the end of stream, ending normally.
4577                    err = ERROR_END_OF_STREAM;
4578                }
4579                ALOGV("end of stream");
4580                return err;
4581            }
4582
4583            if (mode == ReadOptions::SEEK_CLOSEST
4584                || mode == ReadOptions::SEEK_FRAME_INDEX) {
4585                targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
4586            }
4587
4588#if 0
4589            uint32_t syncSampleTime;
4590            CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
4591                        syncSampleIndex, NULL, NULL, &syncSampleTime));
4592
4593            ALOGI("seek to time %lld us => sample at time %lld us, "
4594                 "sync sample at time %lld us",
4595                 seekTimeUs,
4596                 sampleTime * 1000000ll / mTimescale,
4597                 syncSampleTime * 1000000ll / mTimescale);
4598#endif
4599
4600            mCurrentSampleIndex = syncSampleIndex;
4601        }
4602
4603        if (mBuffer != NULL) {
4604            mBuffer->release();
4605            mBuffer = NULL;
4606        }
4607
4608        // fall through
4609    }
4610
4611    off64_t offset = 0;
4612    size_t size = 0;
4613    uint32_t cts, stts;
4614    bool isSyncSample;
4615    bool newBuffer = false;
4616    if (mBuffer == NULL) {
4617        newBuffer = true;
4618
4619        status_t err;
4620        if (!mIsHeif) {
4621            err = mSampleTable->getMetaDataForSample(
4622                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
4623        } else {
4624            err = mItemTable->getImageOffsetAndSize(
4625                    options && options->getSeekTo(&seekTimeUs, &mode) ?
4626                            &mCurrentSampleIndex : NULL, &offset, &size);
4627
4628            cts = stts = 0;
4629            isSyncSample = 0;
4630            ALOGV("image offset %lld, size %zu", (long long)offset, size);
4631        }
4632
4633        if (err != OK) {
4634            return err;
4635        }
4636
4637        err = mGroup->acquire_buffer(&mBuffer);
4638
4639        if (err != OK) {
4640            CHECK(mBuffer == NULL);
4641            return err;
4642        }
4643        if (size > mBuffer->size()) {
4644            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4645            mBuffer->release();
4646            mBuffer = NULL;
4647            return ERROR_BUFFER_TOO_SMALL;
4648        }
4649    }
4650
4651    if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
4652        if (newBuffer) {
4653            ssize_t num_bytes_read =
4654                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4655
4656            if (num_bytes_read < (ssize_t)size) {
4657                mBuffer->release();
4658                mBuffer = NULL;
4659
4660                return ERROR_IO;
4661            }
4662
4663            CHECK(mBuffer != NULL);
4664            mBuffer->set_range(0, size);
4665            mBuffer->meta_data().clear();
4666            mBuffer->meta_data().setInt64(
4667                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4668            mBuffer->meta_data().setInt64(
4669                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4670
4671            if (targetSampleTimeUs >= 0) {
4672                mBuffer->meta_data().setInt64(
4673                        kKeyTargetTime, targetSampleTimeUs);
4674            }
4675
4676            if (isSyncSample) {
4677                mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
4678            }
4679
4680            ++mCurrentSampleIndex;
4681        }
4682
4683        if (!mIsAVC && !mIsHEVC) {
4684            *out = mBuffer;
4685            mBuffer = NULL;
4686
4687            return OK;
4688        }
4689
4690        // Each NAL unit is split up into its constituent fragments and
4691        // each one of them returned in its own buffer.
4692
4693        CHECK(mBuffer->range_length() >= mNALLengthSize);
4694
4695        const uint8_t *src =
4696            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
4697
4698        size_t nal_size = parseNALSize(src);
4699        if (mNALLengthSize > SIZE_MAX - nal_size) {
4700            ALOGE("b/24441553, b/24445122");
4701        }
4702        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
4703            ALOGE("incomplete NAL unit.");
4704
4705            mBuffer->release();
4706            mBuffer = NULL;
4707
4708            return ERROR_MALFORMED;
4709        }
4710
4711        MediaBufferBase *clone = mBuffer->clone();
4712        CHECK(clone != NULL);
4713        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
4714
4715        CHECK(mBuffer != NULL);
4716        mBuffer->set_range(
4717                mBuffer->range_offset() + mNALLengthSize + nal_size,
4718                mBuffer->range_length() - mNALLengthSize - nal_size);
4719
4720        if (mBuffer->range_length() == 0) {
4721            mBuffer->release();
4722            mBuffer = NULL;
4723        }
4724
4725        *out = clone;
4726
4727        return OK;
4728    } else {
4729        // Whole NAL units are returned but each fragment is prefixed by
4730        // the start code (0x00 00 00 01).
4731        ssize_t num_bytes_read = 0;
4732        int32_t drm = 0;
4733        bool usesDRM = (mFormat.findInt32(kKeyIsDRM, &drm) && drm != 0);
4734        if (usesDRM) {
4735            num_bytes_read =
4736                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
4737        } else {
4738            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
4739        }
4740
4741        if (num_bytes_read < (ssize_t)size) {
4742            mBuffer->release();
4743            mBuffer = NULL;
4744
4745            return ERROR_IO;
4746        }
4747
4748        if (usesDRM) {
4749            CHECK(mBuffer != NULL);
4750            mBuffer->set_range(0, size);
4751
4752        } else {
4753            uint8_t *dstData = (uint8_t *)mBuffer->data();
4754            size_t srcOffset = 0;
4755            size_t dstOffset = 0;
4756
4757            while (srcOffset < size) {
4758                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
4759                size_t nalLength = 0;
4760                if (!isMalFormed) {
4761                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
4762                    srcOffset += mNALLengthSize;
4763                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
4764                }
4765
4766                if (isMalFormed) {
4767                    ALOGE("Video is malformed");
4768                    mBuffer->release();
4769                    mBuffer = NULL;
4770                    return ERROR_MALFORMED;
4771                }
4772
4773                if (nalLength == 0) {
4774                    continue;
4775                }
4776
4777                if (dstOffset > SIZE_MAX - 4 ||
4778                        dstOffset + 4 > SIZE_MAX - nalLength ||
4779                        dstOffset + 4 + nalLength > mBuffer->size()) {
4780                    ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
4781                    android_errorWriteLog(0x534e4554, "27208621");
4782                    mBuffer->release();
4783                    mBuffer = NULL;
4784                    return ERROR_MALFORMED;
4785                }
4786
4787                dstData[dstOffset++] = 0;
4788                dstData[dstOffset++] = 0;
4789                dstData[dstOffset++] = 0;
4790                dstData[dstOffset++] = 1;
4791                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
4792                srcOffset += nalLength;
4793                dstOffset += nalLength;
4794            }
4795            CHECK_EQ(srcOffset, size);
4796            CHECK(mBuffer != NULL);
4797            mBuffer->set_range(0, dstOffset);
4798        }
4799
4800        mBuffer->meta_data().clear();
4801        mBuffer->meta_data().setInt64(
4802                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4803        mBuffer->meta_data().setInt64(
4804                kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4805
4806        if (targetSampleTimeUs >= 0) {
4807            mBuffer->meta_data().setInt64(
4808                    kKeyTargetTime, targetSampleTimeUs);
4809        }
4810
4811        if (mIsAVC) {
4812            uint32_t layerId = FindAVCLayerId(
4813                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
4814            mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
4815        }
4816
4817        if (isSyncSample) {
4818            mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
4819        }
4820
4821        ++mCurrentSampleIndex;
4822
4823        *out = mBuffer;
4824        mBuffer = NULL;
4825
4826        return OK;
4827    }
4828}
4829
4830status_t MPEG4Source::fragmentedRead(
4831        MediaBufferBase **out, const ReadOptions *options) {
4832
4833    ALOGV("MPEG4Source::fragmentedRead");
4834
4835    CHECK(mStarted);
4836
4837    *out = NULL;
4838
4839    int64_t targetSampleTimeUs = -1;
4840
4841    int64_t seekTimeUs;
4842    ReadOptions::SeekMode mode;
4843    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4844
4845        int numSidxEntries = mSegments.size();
4846        if (numSidxEntries != 0) {
4847            int64_t totalTime = 0;
4848            off64_t totalOffset = mFirstMoofOffset;
4849            for (int i = 0; i < numSidxEntries; i++) {
4850                const SidxEntry *se = &mSegments[i];
4851                if (totalTime + se->mDurationUs > seekTimeUs) {
4852                    // The requested time is somewhere in this segment
4853                    if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) ||
4854                        (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
4855                        (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
4856                        // requested next sync, or closest sync and it was closer to the end of
4857                        // this segment
4858                        totalTime += se->mDurationUs;
4859                        totalOffset += se->mSize;
4860                    }
4861                    break;
4862                }
4863                totalTime += se->mDurationUs;
4864                totalOffset += se->mSize;
4865            }
4866            mCurrentMoofOffset = totalOffset;
4867            mNextMoofOffset = -1;
4868            mCurrentSamples.clear();
4869            mCurrentSampleIndex = 0;
4870            status_t err = parseChunk(&totalOffset);
4871            if (err != OK) {
4872                return err;
4873            }
4874            mCurrentTime = totalTime * mTimescale / 1000000ll;
4875        } else {
4876            // without sidx boxes, we can only seek to 0
4877            mCurrentMoofOffset = mFirstMoofOffset;
4878            mNextMoofOffset = -1;
4879            mCurrentSamples.clear();
4880            mCurrentSampleIndex = 0;
4881            off64_t tmp = mCurrentMoofOffset;
4882            status_t err = parseChunk(&tmp);
4883            if (err != OK) {
4884                return err;
4885            }
4886            mCurrentTime = 0;
4887        }
4888
4889        if (mBuffer != NULL) {
4890            mBuffer->release();
4891            mBuffer = NULL;
4892        }
4893
4894        // fall through
4895    }
4896
4897    off64_t offset = 0;
4898    size_t size = 0;
4899    uint32_t cts = 0;
4900    bool isSyncSample = false;
4901    bool newBuffer = false;
4902    if (mBuffer == NULL) {
4903        newBuffer = true;
4904
4905        if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4906            // move to next fragment if there is one
4907            if (mNextMoofOffset <= mCurrentMoofOffset) {
4908                return ERROR_END_OF_STREAM;
4909            }
4910            off64_t nextMoof = mNextMoofOffset;
4911            mCurrentMoofOffset = nextMoof;
4912            mCurrentSamples.clear();
4913            mCurrentSampleIndex = 0;
4914            status_t err = parseChunk(&nextMoof);
4915            if (err != OK) {
4916                return err;
4917            }
4918            if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4919                return ERROR_END_OF_STREAM;
4920            }
4921        }
4922
4923        const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
4924        offset = smpl->offset;
4925        size = smpl->size;
4926        cts = mCurrentTime + smpl->compositionOffset;
4927        mCurrentTime += smpl->duration;
4928        isSyncSample = (mCurrentSampleIndex == 0); // XXX
4929
4930        status_t err = mGroup->acquire_buffer(&mBuffer);
4931
4932        if (err != OK) {
4933            CHECK(mBuffer == NULL);
4934            ALOGV("acquire_buffer returned %d", err);
4935            return err;
4936        }
4937        if (size > mBuffer->size()) {
4938            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4939            mBuffer->release();
4940            mBuffer = NULL;
4941            return ERROR_BUFFER_TOO_SMALL;
4942        }
4943    }
4944
4945    const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
4946    MetaDataBase &bufmeta = mBuffer->meta_data();
4947    bufmeta.clear();
4948    if (smpl->encryptedsizes.size()) {
4949        // store clear/encrypted lengths in metadata
4950        bufmeta.setData(kKeyPlainSizes, 0,
4951                smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
4952        bufmeta.setData(kKeyEncryptedSizes, 0,
4953                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
4954        bufmeta.setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
4955        bufmeta.setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
4956        bufmeta.setInt32(kKeyCryptoMode, mCryptoMode);
4957        bufmeta.setData(kKeyCryptoKey, 0, mCryptoKey, 16);
4958    }
4959
4960    if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) {
4961        if (newBuffer) {
4962            if (!isInRange((size_t)0u, mBuffer->size(), size)) {
4963                mBuffer->release();
4964                mBuffer = NULL;
4965
4966                ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
4967                return ERROR_MALFORMED;
4968            }
4969
4970            ssize_t num_bytes_read =
4971                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4972
4973            if (num_bytes_read < (ssize_t)size) {
4974                mBuffer->release();
4975                mBuffer = NULL;
4976
4977                ALOGE("i/o error");
4978                return ERROR_IO;
4979            }
4980
4981            CHECK(mBuffer != NULL);
4982            mBuffer->set_range(0, size);
4983            mBuffer->meta_data().setInt64(
4984                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4985            mBuffer->meta_data().setInt64(
4986                    kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
4987
4988            if (targetSampleTimeUs >= 0) {
4989                mBuffer->meta_data().setInt64(
4990                        kKeyTargetTime, targetSampleTimeUs);
4991            }
4992
4993            if (mIsAVC) {
4994                uint32_t layerId = FindAVCLayerId(
4995                        (const uint8_t *)mBuffer->data(), mBuffer->range_length());
4996                mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
4997            }
4998
4999            if (isSyncSample) {
5000                mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
5001            }
5002
5003            ++mCurrentSampleIndex;
5004        }
5005
5006        if (!mIsAVC && !mIsHEVC) {
5007            *out = mBuffer;
5008            mBuffer = NULL;
5009
5010            return OK;
5011        }
5012
5013        // Each NAL unit is split up into its constituent fragments and
5014        // each one of them returned in its own buffer.
5015
5016        CHECK(mBuffer->range_length() >= mNALLengthSize);
5017
5018        const uint8_t *src =
5019            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
5020
5021        size_t nal_size = parseNALSize(src);
5022        if (mNALLengthSize > SIZE_MAX - nal_size) {
5023            ALOGE("b/24441553, b/24445122");
5024        }
5025
5026        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
5027            ALOGE("incomplete NAL unit.");
5028
5029            mBuffer->release();
5030            mBuffer = NULL;
5031
5032            return ERROR_MALFORMED;
5033        }
5034
5035        MediaBufferBase *clone = mBuffer->clone();
5036        CHECK(clone != NULL);
5037        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
5038
5039        CHECK(mBuffer != NULL);
5040        mBuffer->set_range(
5041                mBuffer->range_offset() + mNALLengthSize + nal_size,
5042                mBuffer->range_length() - mNALLengthSize - nal_size);
5043
5044        if (mBuffer->range_length() == 0) {
5045            mBuffer->release();
5046            mBuffer = NULL;
5047        }
5048
5049        *out = clone;
5050
5051        return OK;
5052    } else {
5053        ALOGV("whole NAL");
5054        // Whole NAL units are returned but each fragment is prefixed by
5055        // the start code (0x00 00 00 01).
5056        ssize_t num_bytes_read = 0;
5057        int32_t drm = 0;
5058        bool usesDRM = (mFormat.findInt32(kKeyIsDRM, &drm) && drm != 0);
5059        void *data = NULL;
5060        bool isMalFormed = false;
5061        if (usesDRM) {
5062            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
5063                isMalFormed = true;
5064            } else {
5065                data = mBuffer->data();
5066            }
5067        } else {
5068            int32_t max_size;
5069            if (!mFormat.findInt32(kKeyMaxInputSize, &max_size)
5070                    || !isInRange((size_t)0u, (size_t)max_size, size)) {
5071                isMalFormed = true;
5072            } else {
5073                data = mSrcBuffer;
5074            }
5075        }
5076
5077        if (isMalFormed || data == NULL) {
5078            ALOGE("isMalFormed size %zu", size);
5079            if (mBuffer != NULL) {
5080                mBuffer->release();
5081                mBuffer = NULL;
5082            }
5083            return ERROR_MALFORMED;
5084        }
5085        num_bytes_read = mDataSource->readAt(offset, data, size);
5086
5087        if (num_bytes_read < (ssize_t)size) {
5088            mBuffer->release();
5089            mBuffer = NULL;
5090
5091            ALOGE("i/o error");
5092            return ERROR_IO;
5093        }
5094
5095        if (usesDRM) {
5096            CHECK(mBuffer != NULL);
5097            mBuffer->set_range(0, size);
5098
5099        } else {
5100            uint8_t *dstData = (uint8_t *)mBuffer->data();
5101            size_t srcOffset = 0;
5102            size_t dstOffset = 0;
5103
5104            while (srcOffset < size) {
5105                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
5106                size_t nalLength = 0;
5107                if (!isMalFormed) {
5108                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
5109                    srcOffset += mNALLengthSize;
5110                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
5111                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
5112                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
5113                }
5114
5115                if (isMalFormed) {
5116                    ALOGE("Video is malformed; nalLength %zu", nalLength);
5117                    mBuffer->release();
5118                    mBuffer = NULL;
5119                    return ERROR_MALFORMED;
5120                }
5121
5122                if (nalLength == 0) {
5123                    continue;
5124                }
5125
5126                if (dstOffset > SIZE_MAX - 4 ||
5127                        dstOffset + 4 > SIZE_MAX - nalLength ||
5128                        dstOffset + 4 + nalLength > mBuffer->size()) {
5129                    ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
5130                    android_errorWriteLog(0x534e4554, "26365349");
5131                    mBuffer->release();
5132                    mBuffer = NULL;
5133                    return ERROR_MALFORMED;
5134                }
5135
5136                dstData[dstOffset++] = 0;
5137                dstData[dstOffset++] = 0;
5138                dstData[dstOffset++] = 0;
5139                dstData[dstOffset++] = 1;
5140                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
5141                srcOffset += nalLength;
5142                dstOffset += nalLength;
5143            }
5144            CHECK_EQ(srcOffset, size);
5145            CHECK(mBuffer != NULL);
5146            mBuffer->set_range(0, dstOffset);
5147        }
5148
5149        mBuffer->meta_data().setInt64(
5150                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
5151        mBuffer->meta_data().setInt64(
5152                kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
5153
5154        if (targetSampleTimeUs >= 0) {
5155            mBuffer->meta_data().setInt64(
5156                    kKeyTargetTime, targetSampleTimeUs);
5157        }
5158
5159        if (isSyncSample) {
5160            mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
5161        }
5162
5163        ++mCurrentSampleIndex;
5164
5165        *out = mBuffer;
5166        mBuffer = NULL;
5167
5168        return OK;
5169    }
5170}
5171
5172MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
5173        const char *mimePrefix) {
5174    for (Track *track = mFirstTrack; track != NULL; track = track->next) {
5175        const char *mime;
5176        if (track->meta.findCString(kKeyMIMEType, &mime)
5177                && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
5178            return track;
5179        }
5180    }
5181
5182    return NULL;
5183}
5184
5185static bool LegacySniffMPEG4(DataSourceBase *source, float *confidence) {
5186    uint8_t header[8];
5187
5188    ssize_t n = source->readAt(4, header, sizeof(header));
5189    if (n < (ssize_t)sizeof(header)) {
5190        return false;
5191    }
5192
5193    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
5194        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
5195        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
5196        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
5197        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
5198        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)
5199        || !memcmp(header, "ftypmif1", 8) || !memcmp(header, "ftypheic", 8)
5200        || !memcmp(header, "ftypmsf1", 8) || !memcmp(header, "ftyphevc", 8)) {
5201        *confidence = 0.4;
5202
5203        return true;
5204    }
5205
5206    return false;
5207}
5208
5209static bool isCompatibleBrand(uint32_t fourcc) {
5210    static const uint32_t kCompatibleBrands[] = {
5211        FOURCC('i', 's', 'o', 'm'),
5212        FOURCC('i', 's', 'o', '2'),
5213        FOURCC('a', 'v', 'c', '1'),
5214        FOURCC('h', 'v', 'c', '1'),
5215        FOURCC('h', 'e', 'v', '1'),
5216        FOURCC('3', 'g', 'p', '4'),
5217        FOURCC('m', 'p', '4', '1'),
5218        FOURCC('m', 'p', '4', '2'),
5219        FOURCC('d', 'a', 's', 'h'),
5220
5221        // Won't promise that the following file types can be played.
5222        // Just give these file types a chance.
5223        FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
5224        FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
5225
5226        FOURCC('3', 'g', '2', 'a'),  // 3GPP2
5227        FOURCC('3', 'g', '2', 'b'),
5228        FOURCC('m', 'i', 'f', '1'),  // HEIF image
5229        FOURCC('h', 'e', 'i', 'c'),  // HEIF image
5230        FOURCC('m', 's', 'f', '1'),  // HEIF image sequence
5231        FOURCC('h', 'e', 'v', 'c'),  // HEIF image sequence
5232    };
5233
5234    for (size_t i = 0;
5235         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
5236         ++i) {
5237        if (kCompatibleBrands[i] == fourcc) {
5238            return true;
5239        }
5240    }
5241
5242    return false;
5243}
5244
5245// Attempt to actually parse the 'ftyp' atom and determine if a suitable
5246// compatible brand is present.
5247// Also try to identify where this file's metadata ends
5248// (end of the 'moov' atom) and report it to the caller as part of
5249// the metadata.
5250static bool BetterSniffMPEG4(DataSourceBase *source, float *confidence) {
5251    // We scan up to 128 bytes to identify this file as an MP4.
5252    static const off64_t kMaxScanOffset = 128ll;
5253
5254    off64_t offset = 0ll;
5255    bool foundGoodFileType = false;
5256    off64_t moovAtomEndOffset = -1ll;
5257    bool done = false;
5258
5259    while (!done && offset < kMaxScanOffset) {
5260        uint32_t hdr[2];
5261        if (source->readAt(offset, hdr, 8) < 8) {
5262            return false;
5263        }
5264
5265        uint64_t chunkSize = ntohl(hdr[0]);
5266        uint32_t chunkType = ntohl(hdr[1]);
5267        off64_t chunkDataOffset = offset + 8;
5268
5269        if (chunkSize == 1) {
5270            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
5271                return false;
5272            }
5273
5274            chunkSize = ntoh64(chunkSize);
5275            chunkDataOffset += 8;
5276
5277            if (chunkSize < 16) {
5278                // The smallest valid chunk is 16 bytes long in this case.
5279                return false;
5280            }
5281
5282        } else if (chunkSize < 8) {
5283            // The smallest valid chunk is 8 bytes long.
5284            return false;
5285        }
5286
5287        // (data_offset - offset) is either 8 or 16
5288        off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset);
5289        if (chunkDataSize < 0) {
5290            ALOGE("b/23540914");
5291            return false;
5292        }
5293
5294        char chunkstring[5];
5295        MakeFourCCString(chunkType, chunkstring);
5296        ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
5297        switch (chunkType) {
5298            case FOURCC('f', 't', 'y', 'p'):
5299            {
5300                if (chunkDataSize < 8) {
5301                    return false;
5302                }
5303
5304                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
5305                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
5306                    if (i == 1) {
5307                        // Skip this index, it refers to the minorVersion,
5308                        // not a brand.
5309                        continue;
5310                    }
5311
5312                    uint32_t brand;
5313                    if (source->readAt(
5314                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
5315                        return false;
5316                    }
5317
5318                    brand = ntohl(brand);
5319
5320                    if (isCompatibleBrand(brand)) {
5321                        foundGoodFileType = true;
5322                        break;
5323                    }
5324                }
5325
5326                if (!foundGoodFileType) {
5327                    return false;
5328                }
5329
5330                break;
5331            }
5332
5333            case FOURCC('m', 'o', 'o', 'v'):
5334            {
5335                moovAtomEndOffset = offset + chunkSize;
5336
5337                done = true;
5338                break;
5339            }
5340
5341            default:
5342                break;
5343        }
5344
5345        offset += chunkSize;
5346    }
5347
5348    if (!foundGoodFileType) {
5349        return false;
5350    }
5351
5352    *confidence = 0.4f;
5353
5354    return true;
5355}
5356
5357static MediaExtractor* CreateExtractor(DataSourceBase *source, void *) {
5358    return new MPEG4Extractor(source);
5359}
5360
5361static MediaExtractor::CreatorFunc Sniff(
5362        DataSourceBase *source, float *confidence, void **,
5363        MediaExtractor::FreeMetaFunc *) {
5364    if (BetterSniffMPEG4(source, confidence)) {
5365        return CreateExtractor;
5366    }
5367
5368    if (LegacySniffMPEG4(source, confidence)) {
5369        ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
5370        return CreateExtractor;
5371    }
5372
5373    return NULL;
5374}
5375
5376extern "C" {
5377// This is the only symbol that needs to be exported
5378__attribute__ ((visibility ("default")))
5379MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
5380    return {
5381        MediaExtractor::EXTRACTORDEF_VERSION,
5382        UUID("27575c67-4417-4c54-8d3d-8e626985a164"),
5383        1, // version
5384        "MP4 Extractor",
5385        Sniff
5386    };
5387}
5388
5389} // extern "C"
5390
5391}  // namespace android
5392