120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen//#define LOG_NDEBUG 0
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor"
1989e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h>
21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h>
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h>
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h>
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <utils/Log.h>
27a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
28a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/MPEG4Extractor.h"
29a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/SampleTable.h"
30a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/ESDS.h"
31a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ABitReader.h>
33d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson#include <media/stagefright/foundation/ABuffer.h>
34ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h>
35a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
36bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
3758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar#include <media/stagefright/foundation/ColorUtils.h>
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h>
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
4018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h>
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h>
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h>
46328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h"
47fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
48937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#ifndef UINT32_MAX
49937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#define UINT32_MAX       (4294967295U)
50937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#endif
51937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
540dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnarenum {
550dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar    // max track header chunk to return
560dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar    kMaxTrackHeaderSize = 32,
570dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar};
580dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource {
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic:
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // Caller retains ownership of both "dataSource" and "sampleTable".
62942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    MPEG4Source(const sp<MPEG4Extractor> &owner,
63942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen                const sp<MetaData> &format,
64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                const sp<DataSource> &dataSource,
6548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                int32_t timeScale,
6605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                const sp<SampleTable> &sampleTable,
6705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                Vector<SidxEntry> &sidx,
68c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                const Trex *trex,
6905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                off64_t firstMoofOffset);
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t start(MetaData *params = NULL);
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t stop();
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual sp<MetaData> getFormat();
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
7705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL);
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
79693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
80693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~MPEG4Source();
81693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate:
837b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex mLock;
847b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
85942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    // keep the MPEG4Extractor around, since we're referencing its data
86942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    sp<MPEG4Extractor> mOwner;
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> mFormat;
88693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<DataSource> mDataSource;
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t mTimescale;
90693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<SampleTable> mSampleTable;
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t mCurrentSampleIndex;
9205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t mCurrentFragmentIndex;
9305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Vector<SidxEntry> &mSegments;
94c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    const Trex *mTrex;
9505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t mFirstMoofOffset;
9605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t mCurrentMoofOffset;
9705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t mNextMoofOffset;
9805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t mCurrentTime;
9905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int32_t mLastParsedTrackId;
10005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int32_t mTrackId;
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int32_t mCryptoMode;    // passed in from extractor
103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int32_t mDefaultIVSize; // passed in from extractor
104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t mCryptoKey[16]; // passed in from extractor
105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentAuxInfoType;
106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentAuxInfoTypeParameter;
10748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    int32_t mCurrentDefaultSampleInfoSize;
108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoCount;
109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoAllocSize;
110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t* mCurrentSampleInfoSizes;
111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoOffsetCount;
112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoOffsetsAllocSize;
113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint64_t* mCurrentSampleInfoOffsets;
114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool mIsAVC;
1163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    bool mIsHEVC;
1176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    size_t mNALLengthSize;
1186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool mStarted;
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBufferGroup *mGroup;
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *mBuffer;
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
125dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool mWantsNALFragments;
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1270024245e134467d120b40099da16c467dc365e76Andreas Huber    uint8_t *mSrcBuffer;
1280024245e134467d120b40099da16c467dc365e76Andreas Huber
1296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    size_t parseNALSize(const uint8_t *data) const;
13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    status_t parseChunk(off64_t *offset);
13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    status_t parseTrackFragmentRun(off64_t offset, off64_t size);
133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    struct TrackFragmentHeaderInfo {
13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        enum Flags {
13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kBaseDataOffsetPresent         = 0x01,
13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kSampleDescriptionIndexPresent = 0x02,
14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDefaultSampleDurationPresent  = 0x08,
14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDefaultSampleSizePresent      = 0x10,
14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDefaultSampleFlagsPresent     = 0x20,
14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDurationIsEmpty               = 0x10000,
14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        };
14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mTrackID;
14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mFlags;
14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint64_t mBaseDataOffset;
14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mSampleDescriptionIndex;
15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mDefaultSampleDuration;
15105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mDefaultSampleSize;
15205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mDefaultSampleFlags;
15305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
15405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint64_t mDataOffset;
15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
15705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
15805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    struct Sample {
15905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t offset;
16005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size_t size;
16105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t duration;
162c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        int32_t compositionOffset;
163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        uint8_t iv[16];
164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Vector<size_t> clearsizes;
165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Vector<size_t> encryptedsizes;
16605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
16705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Vector<Sample> mCurrentSamples;
1686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MPEG4Source(const MPEG4Source &);
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MPEG4Source &operator=(const MPEG4Source &);
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber};
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests
17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding
17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource.
17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track,
17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e.
17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track.
17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource {
18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource(const sp<DataSource> &source);
18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual status_t initCheck() const;
184c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
185c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    virtual status_t getSize(off64_t *size);
18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual uint32_t flags();
18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
188c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    status_t setCachedRange(off64_t offset, size_t size);
18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected:
19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual ~MPEG4DataSource();
19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate:
19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex mLock;
19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    sp<DataSource> mSource;
197c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCachedOffset;
19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    size_t mCachedSize;
19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    uint8_t *mCache;
20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    void clearCache();
20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource(const MPEG4DataSource &);
20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource &operator=(const MPEG4DataSource &);
20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber};
20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    : mSource(source),
20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCachedOffset(0),
21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCachedSize(0),
21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCache(NULL) {
21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() {
21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    clearCache();
21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() {
21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (mCache) {
22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        free(mCache);
22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        mCache = NULL;
22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedOffset = 0;
22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedSize = 0;
22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const {
22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->initCheck();
23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
232c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex::Autolock autoLock(mLock);
23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
235bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar    if (isInRange(mCachedOffset, mCachedSize, offset, size)) {
23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        memcpy(data, &mCache[offset - mCachedOffset], size);
23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return size;
23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->readAt(offset, data, size);
24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
243c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) {
24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->getSize(size);
24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() {
24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->flags();
24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
251c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) {
25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex::Autolock autoLock(mLock);
25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    clearCache();
25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCache = (uint8_t *)malloc(size);
25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (mCache == NULL) {
25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return -ENOMEM;
26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedOffset = offset;
26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedSize = size;
26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (err < (ssize_t)size) {
26850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        clearCache();
26950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
27050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return ERROR_IO;
27150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
27250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
27350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return OK;
27450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
27550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
27650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber////////////////////////////////////////////////////////////////////////////////
27750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
278b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false;
279b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) {
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const uint8_t *data = (const uint8_t *)_data;
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t offset = 0;
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (offset < size) {
284377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT        printf("0x%04zx  ", offset);
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t n = size - offset;
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (n > 16) {
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            n = 16;
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (size_t i = 0; i < 16; ++i) {
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (i == 8) {
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(" ");
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (offset + i < size) {
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("%02x ", data[offset + i]);
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("   ");
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf(" ");
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (size_t i = 0; i < n; ++i) {
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (isprint(data[offset + i])) {
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("%c", data[offset + i]);
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(".");
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("\n");
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        offset += 16;
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) {
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    switch (fourcc) {
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
32218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AAC;
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
32518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
327371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
32818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
329371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
33118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_MPEG4;
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
334e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('h', '2', '6', '3'):
335e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('H', '2', '6', '3'):
33618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_H263;
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
33918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_AVC;
34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', '1'):
3423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'e', 'v', '1'):
3433b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            return MEDIA_MIMETYPE_VIDEO_HEVC;
34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
345dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            CHECK(!"should not be here.");
34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) {
35148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) {
35248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // AMR NB audio is always mono, 8kHz
35348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *channels = 1;
35448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *rate = 8000;
35548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return true;
35648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) {
35748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // AMR WB audio is always mono, 16kHz
35848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *channels = 1;
35948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *rate = 16000;
36048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return true;
36148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
36248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    return false;
36348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen}
36448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
365693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
366c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    : mMoofOffset(0),
367928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang      mMoofFound(false),
368928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang      mMdatFound(false),
36905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mDataSource(source),
370bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber      mInitCheck(NO_INIT),
3717be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber      mHasVideo(false),
372fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen      mHeaderTimescale(0),
37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mFirstTrack(NULL),
37472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber      mLastTrack(NULL),
375dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFileMetaData(new MetaData),
376dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFirstSINF(NULL),
377dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mIsDrm(false) {
37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() {
38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (track) {
38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        Track *next = track->next;
38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete track;
38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = next;
38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mFirstTrack = mLastTrack = NULL;
389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    SINF *sinf = mFirstSINF;
391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (sinf) {
392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        SINF *next = sinf->next;
3938da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        delete[] sinf->IPMPData;
394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        delete sinf;
395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf = next;
396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mFirstSINF = NULL;
398ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
399ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mPssh.size(); i++) {
400ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        delete [] mPssh[i].data;
401ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
40405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const {
40505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return CAN_PAUSE |
40605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ((mMoofOffset == 0 || mSidxEntries.size() != 0) ?
40705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
40805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
40905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() {
4117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    status_t err;
4127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if ((err = readMetaData()) != OK) {
41372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return new MetaData;
4147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
4157be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
41672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return mFileMetaData;
4177be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
4187be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() {
42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
422ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        ALOGV("MPEG4Extractor::countTracks: no tracks");
423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return 0;
42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (track) {
429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++n;
43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
433a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("MPEG4Extractor::countTracks: %zu tracks", n);
434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(
4387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t index, uint32_t flags) {
43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return NULL;
44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
454371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
455371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
456371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
457371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
4587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if ((flags & kIncludeExtensiveMetaData)
4597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            && !track->includes_expensive_metadata) {
4607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        track->includes_expensive_metadata = true;
4617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
4627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        const char *mime;
4637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
4647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (!strncasecmp("video/", mime, 6)) {
46505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (mMoofOffset > 0) {
46605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                int64_t duration;
46705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (track->meta->findInt64(kKeyDuration, &duration)) {
46805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    // nothing fancy, just pick a frame near 1/4th of the duration
46905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    track->meta->setInt64(
47005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            kKeyThumbnailTime, duration / 4);
47105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            } else {
47305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t sampleIndex;
47405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t sampleTime;
47505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
47605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        && track->sampleTable->getMetaDataForSample(
47705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            sampleIndex, NULL /* offset */, NULL /* size */,
47805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            &sampleTime) == OK) {
47905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    track->meta->setInt64(
48005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            kKeyThumbnailTime,
48105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            ((int64_t)sampleTime * 1000000) / track->timescale);
48205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
4837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            }
4840dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar
4850dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar            // MPEG2 tracks do not provide CSD, so read the stream header
4860dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar            if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
4870dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                off64_t offset;
4880dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                size_t size;
4890dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                if (track->sampleTable->getMetaDataForSample(
4900dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                            0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
4910dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    if (size > kMaxTrackHeaderSize) {
4920dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                        size = kMaxTrackHeaderSize;
4930dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    }
4940dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    uint8_t header[kMaxTrackHeaderSize];
4950dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
4960dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                        track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
4970dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    }
4980dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                }
4990dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar            }
5007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
5017e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
5027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return track->meta;
50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
50648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) {
50748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[0] = x >> 24;
50848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[1] = (x >> 16) & 0xff;
50948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[2] = (x >> 8) & 0xff;
51048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[3] = x & 0xff;
51148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[4] = '\0';
51248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen}
51348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() {
515bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    if (mInitCheck != NO_INIT) {
516bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        return mInitCheck;
51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
519c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset = 0;
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
521928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang    bool sawMoovOrSidx = false;
522928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
523928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang    while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) {
524a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        off64_t orig_offset = offset;
52505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        err = parseChunk(&offset, 0);
526a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen
5274ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar        if (err != OK && err != UNKNOWN_ERROR) {
5284ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar            break;
5294ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar        } else if (offset <= orig_offset) {
530a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // only continue parsing if the offset was advanced,
531a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // otherwise we might end up in an infinite loop
532ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset);
533a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            err = ERROR_MALFORMED;
534a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            break;
535928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang        } else if (err == UNKNOWN_ERROR) {
536928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            sawMoovOrSidx = true;
53705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
5397be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
540bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    if (mInitCheck == OK) {
54172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        if (mHasVideo) {
542bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber            mFileMetaData->setCString(
543bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
54472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else {
54572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
54672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
547bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    } else {
548bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        mInitCheck = err;
54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
551bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    CHECK_NE(err, (status_t)NO_INIT);
552ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
553ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // copy pssh data into file metadata
554c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen    uint64_t psshsize = 0;
555ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mPssh.size(); i++) {
556ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        psshsize += 20 + mPssh[i].datalen;
557ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
558c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen    if (psshsize > 0 && psshsize <= UINT32_MAX) {
559ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        char *buf = (char*)malloc(psshsize);
5606a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen        if (!buf) {
5616a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            ALOGE("b/28471206");
5626a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            return NO_MEMORY;
5636a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen        }
564ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        char *ptr = buf;
565ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        for (size_t i = 0; i < mPssh.size(); i++) {
566ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
567ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
568ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ptr += (20 + mPssh[i].datalen);
569ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
570ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize);
571ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        free(buf);
572ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
573bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    return mInitCheck;
57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mFirstSINF == NULL) {
578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return NULL;
579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    SINF *sinf = mFirstSINF;
582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (sinf && (trackID != sinf->trackID)) {
583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf = sinf->next;
584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (sinf == NULL) {
587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return NULL;
588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *len = sinf->len;
591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return sinf->IPMPData;
592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
59556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset,
596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        const sp<DataSource> DataSource, uint8_t *numOfBytes) {
597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint32_t size = 0;
598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t data;
599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    bool moreData = true;
600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *numOfBytes = 0;
601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (moreData) {
603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (DataSource->readAt(offset, &data, 1) < 1) {
604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return -1;
605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        offset ++;
607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        moreData = (data >= 128) ? true : false;
608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size = (size << 7) | (data & 0x7f); // Take last 7 bits
609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        (*numOfBytes) ++;
610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return size;
613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
61584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF(
61684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t * /* offset */, off64_t data_offset) {
617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t updateIdTag;
618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset ++;
622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t numOfBytes;
628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size < 0) {
630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset += numOfBytes;
633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while(size >= 11 ) {
635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t descriptorTag;
636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset ++;
640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t buffer[8];
646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        //ObjectDescriptorID and ObjectDescriptor url flag
647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset += 2;
651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if ((buffer[1] >> 5) & 0x0001) { //url flag is set
653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset += 8;
660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        SINF *sinf = new SINF;
667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->trackID = U16_AT(&buffer[3]);
668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->IPMPDescriptorID = buffer[7];
669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->next = mFirstSINF;
670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mFirstSINF = sinf;
671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size -= (8 + 2 + 1);
673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size != 0) {
676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset ++;
683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size = readSize(data_offset, mDataSource, &numOfBytes);
689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size < 0) {
690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset += numOfBytes;
693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (size > 0) {
695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t tag;
696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t dataLen;
697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset ++;
701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t id;
704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dataLen = readSize(data_offset, mDataSource, &numOfBytes);
705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (dataLen < 0) {
706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            } else if (dataLen < 4) {
708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset += numOfBytes;
711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (mDataSource->readAt(data_offset, &id, 1) < 1) {
713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset ++;
716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            SINF *sinf = mFirstSINF;
718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (sinf && (sinf->IPMPDescriptorID != id)) {
719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                sinf = sinf->next;
720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (sinf == NULL) {
722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            sinf->len = dataLen - 3;
7258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            sinf->IPMPData = new (std::nothrow) char[sinf->len];
7268da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (sinf->IPMPData == NULL) {
7278da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
7288da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
729f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara            data_offset += 2;
730dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
731f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara            if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) {
732dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
733dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
734dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset += sinf->len;
735dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
736dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size -= (dataLen + numOfBytes + 1);
737dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
738dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
739dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
740dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size != 0) {
741dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return UNKNOWN_ERROR;  // Return a dummy error.
745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
74772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder {
74872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
74972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        : mPath(path) {
75072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        mPath->push(chunkType);
75172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
75272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
75372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    ~PathAdder() {
75472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        mPath->pop();
75572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
75672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate:
75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    Vector<uint32_t> *mPath;
75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder(const PathAdder &);
76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder &operator=(const PathAdder &);
76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber};
76372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
76472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) {
76572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return path.size() >= 5
76672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[0] == FOURCC('m', 'o', 'o', 'v')
76772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[1] == FOURCC('u', 'd', 't', 'a')
76872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[2] == FOURCC('m', 'e', 't', 'a')
76972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[3] == FOURCC('i', 'l', 's', 't');
77072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
77172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
7728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) {
7738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return path.size() >= 2
7748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            && path[0] == FOURCC('m', 'o', 'o', 'v')
7758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            && path[1] == FOURCC('m', 'e', 't', 'a')
7768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            && (depth == 2
7778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || (depth == 3
778ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                    && (path[2] == FOURCC('h', 'd', 'l', 'r')
779ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                    ||  path[2] == FOURCC('i', 'l', 's', 't')
7808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    ||  path[2] == FOURCC('k', 'e', 'y', 's'))));
7818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
7828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
78372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string.
7843724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissenstatic bool convertTimeToDate(int64_t time_1904, String8 *s) {
7853724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    // delta between mpeg4 time and unix epoch time
7863724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    static const int64_t delta = (((66 * 365 + 17) * 24) * 3600);
7873724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    if (time_1904 < INT64_MIN + delta) {
7883724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen        return false;
7893724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    }
7903724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    time_t time_1970 = time_1904 - delta;
79172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
79272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    char tmp[32];
7933724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    struct tm* tm = gmtime(&time_1970);
7943724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    if (tm != NULL &&
7953724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
7963724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen        s->setTo(tmp);
7973724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen        return true;
7983724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    }
7993724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    return false;
80072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
80172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
802c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
803ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth);
804452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen
805452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    if (*offset < 0) {
806452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        ALOGE("b/23540914");
807452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        return ERROR_MALFORMED;
808452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    }
80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t hdr[2];
81034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint64_t chunk_size = ntohl(hdr[0]);
8142d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer    int32_t chunk_type = ntohl(hdr[1]);
815c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t data_offset = *offset + 8;
81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (chunk_size == 1) {
81834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_IO;
82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        chunk_size = ntoh64(chunk_size);
82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        data_offset += 8;
82371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber
82471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        if (chunk_size < 16) {
82571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber            // The smallest valid chunk is 16 bytes long in this case.
82671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber            return ERROR_MALFORMED;
82771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        }
828a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen    } else if (chunk_size == 0) {
829a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        if (depth == 0) {
830a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // atom extends to end of file
831a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            off64_t sourceSize;
832a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            if (mDataSource->getSize(&sourceSize) == OK) {
833a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                chunk_size = (sourceSize - *offset);
834a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            } else {
835a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                // XXX could we just pick a "sufficiently large" value here?
836a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                ALOGE("atom size is 0, and data source has no size");
837a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                return ERROR_MALFORMED;
838a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            }
839a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        } else {
840a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // not allowed for non-toplevel atoms, skip it
841a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            *offset += 4;
842a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            return OK;
843a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        }
84471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber    } else if (chunk_size < 8) {
84571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        // The smallest valid chunk is 8 bytes long.
846a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGE("invalid chunk size: %" PRIu64, chunk_size);
84771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        return ERROR_MALFORMED;
84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    char chunk[5];
85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MakeFourCCString(chunk_type, chunk);
852ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth);
85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
854b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    if (kUseHexDump) {
855b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        static const char kWhitespace[] = "                                        ";
856b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
857b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size);
85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
859b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        char buffer[256];
860b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t n = chunk_size;
861b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        if (n > sizeof(buffer)) {
862b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            n = sizeof(buffer);
863b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        }
864b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        if (mDataSource->readAt(*offset, buffer, n)
865b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                < (ssize_t)n) {
866b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            return ERROR_IO;
867b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        }
868ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
869b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        hexdump(buffer, n);
870b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    }
87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
87272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder autoAdder(&mPath, chunk_type);
87372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
874452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    // (data_offset - *offset) is either 8 or 16
875452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    off64_t chunk_data_size = chunk_size - (data_offset - *offset);
876452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    if (chunk_data_size < 0) {
877452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        ALOGE("b/23540914");
878452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        return ERROR_MALFORMED;
879452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    }
88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
88172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (chunk_type != FOURCC('c', 'p', 'r', 't')
882515e855eae78aa495da58356486aaa666cb57fd1James Dong            && chunk_type != FOURCC('c', 'o', 'v', 'r')
88372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            && mPath.size() == 5 && underMetaDataPath(mPath)) {
884c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t stop_offset = *offset + chunk_size;
88572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        *offset = data_offset;
88672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        while (*offset < stop_offset) {
88772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            status_t err = parseChunk(offset, depth + 1);
88872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (err != OK) {
88972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return err;
89072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
89172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
892bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
893bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (*offset != stop_offset) {
894bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
895bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
89672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
89772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return OK;
89872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
89972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    switch(chunk_type) {
90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'o', 'o', 'v'):
90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'r', 'a', 'k'):
90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'i', 'a'):
90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'i', 'n', 'f'):
90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('d', 'i', 'n', 'f'):
90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'b', 'l'):
90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'v', 'e', 'x'):
90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'o', 'o', 'f'):
90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'r', 'a', 'f'):
91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'f', 'r', 'a'):
91172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('u', 'd', 't', 'a'):
91272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('i', 'l', 's', 't'):
913ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'i', 'n', 'f'):
914ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'c', 'h', 'i'):
9150a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        case FOURCC('e', 'd', 't', 's'):
91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
917928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) {
918928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang                // store the offset of the first segment
919928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang                mMoofFound = true;
920928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang                mMoofOffset = *offset;
921928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            }
922928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
92350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
924a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
92550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
926b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                if (mDataSource->flags()
927b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                        & (DataSource::kWantsPrefetching
928b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                            | DataSource::kIsCachingDataSource)) {
92950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    sp<MPEG4DataSource> cachedSource =
93050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                        new MPEG4DataSource(mDataSource);
93150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
93250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
93350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                        mDataSource = cachedSource;
93450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    }
93550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                }
9361edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber
937f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                if (mLastTrack == NULL)
938f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                    return ERROR_MALFORMED;
939f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
9401edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber                mLastTrack->sampleTable = new SampleTable(mDataSource);
94150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            }
94250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
9436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber            bool isTrack = false;
944bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
9456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                isTrack = true;
9466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
947bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                Track *track = new Track;
948bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->next = NULL;
949bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                if (mLastTrack) {
950bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    mLastTrack->next = track;
951bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                } else {
952bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    mFirstTrack = track;
953bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                }
954bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                mLastTrack = track;
955bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
956bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->meta = new MetaData;
957bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->includes_expensive_metadata = false;
9586f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                track->skipTrack = false;
959bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->timescale = 0;
960bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
961bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
962bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
963c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset;
96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
972bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
973bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
974bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
975bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
9766f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber            if (isTrack) {
9770386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                int32_t trackId;
9780386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                // There must be exact one track header per track.
9790386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
9800386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                    mLastTrack->skipTrack = true;
9810386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                }
9826f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                if (mLastTrack->skipTrack) {
9836f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    Track *cur = mFirstTrack;
9846f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
9856f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    if (cur == mLastTrack) {
9866f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        delete cur;
9876f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        mFirstTrack = mLastTrack = NULL;
9886f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    } else {
9896f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        while (cur && cur->next != mLastTrack) {
9906f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                            cur = cur->next;
9916f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        }
9926f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        cur->next = NULL;
9936f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        delete mLastTrack;
9946f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        mLastTrack = cur;
9956f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    }
9966f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
9976f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    return OK;
9986f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                }
9996f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
1000bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                status_t err = verifyTrack(mLastTrack);
1001bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1002bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                if (err != OK) {
1003bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    return err;
1004bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                }
1005bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
1006bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                mInitCheck = OK;
100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1008dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (!mIsDrm) {
1009dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return UNKNOWN_ERROR;  // Return a dummy error.
1010dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                } else {
1011dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return OK;
1012dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10170a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        case FOURCC('e', 'l', 's', 't'):
10180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        {
10190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
10200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
10210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            // See 14496-12 8.6.6
10220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            uint8_t version;
10230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
10240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                return ERROR_IO;
10250a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            }
10260a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10270a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            uint32_t entry_count;
10280a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) {
10290a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                return ERROR_IO;
10300a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            }
10310a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10320a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            if (entry_count != 1) {
10330a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                // we only support a single entry at the moment, for gapless playback
10340a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                ALOGW("ignoring edit list with %d entries", entry_count);
1035fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen            } else if (mHeaderTimescale == 0) {
1036210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen                ALOGW("ignoring edit list because timescale is 0");
10370a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            } else {
10380a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                off64_t entriesoffset = data_offset + 8;
10390a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                uint64_t segment_duration;
10400a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                int64_t media_time;
10410a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10420a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                if (version == 1) {
10430a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    if (!mDataSource->getUInt64(entriesoffset, &segment_duration) ||
10440a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                            !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) {
10450a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                        return ERROR_IO;
10460a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    }
10470a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                } else if (version == 0) {
10480a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    uint32_t sd;
10490a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    int32_t mt;
10500a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    if (!mDataSource->getUInt32(entriesoffset, &sd) ||
10510a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                            !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) {
10520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                        return ERROR_IO;
10530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    }
10540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    segment_duration = sd;
10550a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    media_time = mt;
10560a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                } else {
10570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    return ERROR_IO;
10580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                }
10590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
1060fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                uint64_t halfscale = mHeaderTimescale / 2;
1061fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale;
1062fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale;
10630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                int64_t duration;
10650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                int32_t samplerate;
10661391f933b49cfb56da9aa63f723de83b076cf888Robert Shih                if (!mLastTrack) {
10671391f933b49cfb56da9aa63f723de83b076cf888Robert Shih                    return ERROR_MALFORMED;
10681391f933b49cfb56da9aa63f723de83b076cf888Robert Shih                }
10690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                if (mLastTrack->meta->findInt64(kKeyDuration, &duration) &&
10700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                        mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) {
10710a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10720a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    int64_t delay = (media_time  * samplerate + 500000) / 1000000;
10730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
10740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
1075608fe1d6b2ea4d88245a109afe2bfba580881a16Wei Jia                    int64_t paddingus = duration - (int64_t)(segment_duration + media_time);
1076465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                    if (paddingus < 0) {
1077465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        // track duration from media header (which is what kKeyDuration is) might
1078465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        // be slightly shorter than the segment duration, which would make the
1079465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        // padding negative. Clamp to zero.
1080465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        paddingus = 0;
1081465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                    }
10820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000;
10830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples);
10840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                }
10850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            }
10860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            break;
10870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        }
10880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('f', 'r', 'm', 'a'):
1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        {
10910517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
10920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
109348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t original_fourcc;
1094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) {
1095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            original_fourcc = ntohl(original_fourcc);
1098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("read original format: %d", original_fourcc);
1099f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1100f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1101f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1102f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
110448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t num_channels = 0;
110548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t sample_rate = 0;
110648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
110748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
110848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
110948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            }
1110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('t', 'e', 'n', 'c'):
1114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        {
11150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
11160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (chunk_size < 32) {
1118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte
1122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // default IV size, 16 bytes default KeyID
1123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // (ISO 23001-7)
1124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            char buf[4];
1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memset(buf, 0, 4);
1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) {
1127ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf));
1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (defaultAlgorithmId > 1) {
1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // only 0 (clear) and 1 (AES-128) are valid
1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memset(buf, 0, 4);
1136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) {
1137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t defaultIVSize = ntohl(*((int32_t*)buf));
1140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((defaultAlgorithmId == 0 && defaultIVSize != 0) ||
1142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                    (defaultAlgorithmId != 0 && defaultIVSize == 0)) {
1143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // only unencrypted data must have 0 IV size
1144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            } else if (defaultIVSize != 0 &&
1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                    defaultIVSize != 8 &&
1147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                    defaultIVSize != 16) {
1148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // only supported sizes are 0, 8 and 16
1149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint8_t defaultKeyId[16];
1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) {
1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1158f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1159f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1160f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1161ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId);
1162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize);
1163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16);
1164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1166ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
116720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'k', 'h', 'd'):
116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
11690517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
11700517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1171ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            status_t err;
1172ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
1173ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                return err;
117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
117520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
117720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('p', 's', 's', 'h'):
1180ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        {
11810517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
11820517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            PsshInfo pssh;
1184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) {
1186ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1187ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1188ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1189ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t psshdatalen = 0;
1190ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) {
1191ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1192ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1193ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            pssh.datalen = ntohl(psshdatalen);
1194ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("pssh data size: %d", pssh.datalen);
1195c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen            if (chunk_size < 20 || pssh.datalen > chunk_size - 20) {
1196ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // pssh data length exceeds size of containing box
1197ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1198ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
12008da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            pssh.data = new (std::nothrow) uint8_t[pssh.datalen];
12018da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (pssh.data == NULL) {
12028da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
12038da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
1204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("allocated pssh @ %p", pssh.data);
1205ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ssize_t requested = (ssize_t) pssh.datalen;
1206ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
1207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1209ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mPssh.push_back(pssh);
1210ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1211ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1212ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1213ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'h', 'd'):
121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
12160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
12170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1218202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih            if (chunk_data_size < 4 || mLastTrack == NULL) {
121920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
122020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
122120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
122220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t version;
122334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, &version, sizeof(version))
122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(version)) {
122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1229c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t timescale_offset;
123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 16;
123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else if (version == 0) {
123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 8;
123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t timescale;
124034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        timescale_offset, &timescale, sizeof(timescale))
124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(timescale)) {
124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12462e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang            if (!timescale) {
12472e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang                ALOGE("timescale should not be ZERO.");
12482e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang                return ERROR_MALFORMED;
12492e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang            }
12502e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang
125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->timescale = ntohl(timescale);
125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1253c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            // 14496-12 says all ones means indeterminate, but some files seem to use
1254c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            // 0 instead. We treat both the same.
125505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            int64_t duration = 0;
125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
125734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration, sizeof(duration))
125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration)) {
126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
1262c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration != -1) {
1263c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = ntoh64(duration);
1264c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
126520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
126605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t duration32;
126734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration32, sizeof(duration32))
126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration32)) {
127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
127205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (duration32 != 0xffffffff) {
127305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    duration = ntohl(duration32);
127405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1276e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake            if (duration != 0 && mLastTrack->timescale != 0) {
1277c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mLastTrack->meta->setInt64(
1278c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                        kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
1279c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            uint8_t lang[2];
12827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            off64_t lang_offset;
12837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (version == 1) {
12847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                lang_offset = timescale_offset + 4 + 8;
12857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else if (version == 0) {
12867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                lang_offset = timescale_offset + 4 + 4;
12877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else {
12887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return ERROR_IO;
12897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
12907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
12917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
12927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                    < (ssize_t)sizeof(lang)) {
12937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return ERROR_IO;
12947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
12957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
12967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // To get the ISO-639-2/T three character language code
12977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // 1 bit pad followed by 3 5-bits characters. Each character
12987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // is packed as the difference between its ASCII value and 0x60.
12997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            char lang_code[4];
13007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
13017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
13027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[2] = (lang[1] & 0x1f) + 0x60;
13037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[3] = '\0';
13047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            mLastTrack->meta->setCString(
13067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                    kKeyMediaLanguage, lang_code);
13077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
130920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
131020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
131120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'd'):
131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
131320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 8) {
131420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
131520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
131620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
131720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8];
1318c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            if (chunk_data_size < (off64_t)sizeof(buffer)) {
1319bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1320bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
1321bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
132234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, 8) < 8) {
132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
132620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
132820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
132920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
133020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
133120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t entry_count = U32_AT(&buffer[4]);
133320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (entry_count > 1) {
13353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // For 3GPP timed text, there could be multiple tx3g boxes contain
13363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // multiple text display formats. These formats will be used to
13373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // display the timed text.
1338ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // For encrypted files, there may also be more than one entry.
13393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                const char *mime;
1340f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1341f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                if (mLastTrack == NULL)
1342f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                    return ERROR_MALFORMED;
1343f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
13443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1345ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
1346ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                        strcasecmp(mime, "application/octet-stream")) {
13473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    // For now we only support a single type of media per track.
13483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    mLastTrack->skipTrack = true;
13493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    *offset += chunk_size;
13503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    break;
13513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                }
135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1353c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + 8;
135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            for (uint32_t i = 0; i < entry_count; ++i) {
135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1361bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1362bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1363bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1364bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
136948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        case FOURCC('e', 'n', 'c', 'a'):
137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
1371371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
137320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8 + 20];
137420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
137520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic AudioSampleEntry size.
137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
137720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
137820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
137934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
138020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
138220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1384b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
138548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t num_channels = U16_AT(&buffer[16]);
138620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
138781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint16_t sample_size = U16_AT(&buffer[18]);
138881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
138981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
1390f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1391f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1392f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
139348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
139448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                // if the chunk type is enca, we'll get the type from the sinf/frma box later
139548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
139648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
139848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
139981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                   chunk, num_channels, sample_size, sample_rate);
140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
140120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1403c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + sizeof(buffer);
140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
140620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
141020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1411bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1412bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1413bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1414bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
141620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
141820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
1419ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('e', 'n', 'c', 'v'):
142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
1421e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('H', '2', '6', '3'):
1422e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('h', '2', '6', '3'):
142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
14243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', '1'):
14253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'e', 'v', '1'):
142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
14277be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber            mHasVideo = true;
14287be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[78];
143020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic VideoSampleEntry size.
143220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
143534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1440b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t width = U16_AT(&buffer[6 + 18]);
144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t height = U16_AT(&buffer[6 + 20]);
144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1444ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // The video sample is not standard-compliant if it has invalid dimension.
1445a6256238d9015c42129fe43791968768fe501efaJames Dong            // Use some default width and height value, and
1446a6256238d9015c42129fe43791968768fe501efaJames Dong            // let the decoder figure out the actual width and height (and thus
1447a6256238d9015c42129fe43791968768fe501efaJames Dong            // be prepared for INFO_FOMRAT_CHANGED event).
1448a6256238d9015c42129fe43791968768fe501efaJames Dong            if (width == 0)  width  = 352;
1449a6256238d9015c42129fe43791968768fe501efaJames Dong            if (height == 0) height = 288;
1450a6256238d9015c42129fe43791968768fe501efaJames Dong
1451134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            // printf("*** coding='%s' width=%d height=%d\n",
1452134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            //        chunk, width, height);
145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1454f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1455f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1456f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1457ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
1458ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // if the chunk type is encv, we'll get the type from the sinf/frma box later
1459ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1460ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyWidth, width);
146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyHeight, height);
146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1464c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
146520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + sizeof(buffer);
146620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
146720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
146820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
146920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1472bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1473bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1474bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1475bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'c', 'o'):
148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('c', 'o', '6', '4'):
148120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1482274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1483274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1484274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
148520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
148620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setChunkOffsetParams(
148720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
148820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14890517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
14900517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
149120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
149220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
149320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
149420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
149520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
149720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
149820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'c'):
149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1500274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1501274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1502274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleToChunkParams(
150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
15080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
150920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
151020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
151120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
151220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
151320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
151620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'z'):
151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'z', '2'):
151820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1519274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1520274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1521274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
152220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleSizeParams(
152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
15270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
153020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1532738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            size_t max_size;
153349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
153449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber
153549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            if (err != OK) {
153649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber                return err;
153749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            }
1538738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
153905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (max_size != 0) {
154005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // Assume that a given buffer only contains at most 10 chunks,
154105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // each chunk originally prefixed with a 2 byte length will
154205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
154305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // and thus will grow by 2 bytes per chunk.
1544beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                if (max_size > SIZE_MAX - 10 * 2) {
1545beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    ALOGE("max sample size too big: %zu", max_size);
1546beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    return ERROR_MALFORMED;
1547beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                }
154805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
154905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            } else {
155005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // No size was specified. Pick a conservatively large size.
1551beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                uint32_t width, height;
1552beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) ||
1553beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) {
155405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    ALOGE("No width or height, assuming worst case 1080p");
1555f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    width = 1920;
1556f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    height = 1080;
1557beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                } else {
1558beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // A resolution was specified, check that it's not too big. The values below
1559beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // were chosen so that the calculations below don't cause overflows, they're
1560beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // not indicating that resolutions up to 32kx32k are actually supported.
1561beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    if (width > 32768 || height > 32768) {
1562beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                        ALOGE("can't support %u x %u video", width, height);
1563beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                        return ERROR_MALFORMED;
1564beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    }
156505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
1566f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar
15674256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen                const char *mime;
15684256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
156907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
157007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
157107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    // AVC & HEVC requires compression ratio of at least 2, and uses
1572f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // macroblocks
1573f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192;
1574f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                } else {
1575f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // For all other formats there is no minimum compression
1576f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // ratio. Use compression ratio of 1.
1577f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    max_size = width * height * 3 / 2;
157805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
1579f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
158005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
1581113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong
15824256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen            // NOTE: setting another piece of metadata invalidates any pointers (such as the
15834256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen            // mimetype) previously obtained, so don't cache them.
1584113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            const char *mime;
1585113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1586113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            // Calculate average frame rate.
1587113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            if (!strncasecmp("video/", mime, 6)) {
1588113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                size_t nSamples = mLastTrack->sampleTable->countSamples();
1589949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                if (nSamples == 0) {
1590949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    int32_t trackId;
1591949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
1592949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        for (size_t i = 0; i < mTrex.size(); i++) {
1593949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            Trex *t = &mTrex.editItemAt(i);
1594949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            if (t->track_ID == (uint32_t) trackId) {
1595949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                if (t->default_sample_duration > 0) {
1596949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                    int32_t frameRate =
1597949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                            mLastTrack->timescale / t->default_sample_duration;
1598949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                    mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1599949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                }
1600949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                break;
1601949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            }
1602949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        }
1603949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    }
1604949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                } else {
1605949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    int64_t durationUs;
1606949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
1607949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        if (durationUs > 0) {
1608949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            int32_t frameRate = (nSamples * 1000000LL +
1609949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                        (durationUs >> 1)) / durationUs;
1610949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1611949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        }
1612113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                    }
1613113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                }
1614113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            }
1615113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong
161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 't', 's'):
162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1621274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1622274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1623274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
16240517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
162720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setTimeToSampleParams(
162820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
162920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
163020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
163120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
163220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
163320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
163420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
163520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
163620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16374931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        case FOURCC('c', 't', 't', 's'):
16384931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        {
1639274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1640274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1641274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
16420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16430517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
16444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            status_t err =
16454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                mLastTrack->sampleTable->setCompositionTimeToSampleParams(
16464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                        data_offset, chunk_data_size);
16474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
16484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            if (err != OK) {
16494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                return err;
16504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            }
16514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
16524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            break;
16534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        }
16544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
165520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 's'):
165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1657274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1658274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1659274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
16600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16610517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
166220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
166320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSyncSampleParams(
166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
166520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
166620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
166720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
167120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1673afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        // \xA9xyz
1674e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh        case FOURCC(0xA9, 'x', 'y', 'z'):
16754948818cb91176df74c972ac27b2f392b5d148bcJames Dong        {
16760517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16770517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1678afd492436efc7f66b958da14659b52232efa5910Marco Nelissen            // Best case the total data length inside "\xA9xyz" box
1679afd492436efc7f66b958da14659b52232efa5910Marco Nelissen            // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/",
16804948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // where "\x00\x04" is the text string length with value = 4,
16814948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // "\0x15\xc7" is the language code = en, and "0+0" is a
16824948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // location (string) value with longitude = 0 and latitude = 0.
16834948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (chunk_data_size < 8) {
16844948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_MALFORMED;
16854948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
16864948818cb91176df74c972ac27b2f392b5d148bcJames Dong
16874948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // Worst case the location string length would be 18,
16884948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // for instance +90.0000-180.0000, without the trailing "/" and
16894948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // the string length + language code.
16904948818cb91176df74c972ac27b2f392b5d148bcJames Dong            char buffer[18];
16914948818cb91176df74c972ac27b2f392b5d148bcJames Dong
16924948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // Substracting 5 from the data size is because the text string length +
16934948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
16944948818cb91176df74c972ac27b2f392b5d148bcJames Dong            off64_t location_length = chunk_data_size - 5;
16954948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (location_length >= (off64_t) sizeof(buffer)) {
16964948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_MALFORMED;
16974948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
16984948818cb91176df74c972ac27b2f392b5d148bcJames Dong
16994948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (mDataSource->readAt(
17004948818cb91176df74c972ac27b2f392b5d148bcJames Dong                        data_offset + 4, buffer, location_length) < location_length) {
17014948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_IO;
17024948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17034948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17044948818cb91176df74c972ac27b2f392b5d148bcJames Dong            buffer[location_length] = '\0';
17054948818cb91176df74c972ac27b2f392b5d148bcJames Dong            mFileMetaData->setCString(kKeyLocation, buffer);
17064948818cb91176df74c972ac27b2f392b5d148bcJames Dong            break;
17074948818cb91176df74c972ac27b2f392b5d148bcJames Dong        }
17084948818cb91176df74c972ac27b2f392b5d148bcJames Dong
170920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('e', 's', 'd', 's'):
171020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
17110517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17120517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
171320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 4) {
171420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
171520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
171620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
171720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[256];
1718c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            if (chunk_data_size > (off64_t)sizeof(buffer)) {
171920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
172020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
172234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
172920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1732f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1733f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1734f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
173520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
173620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
173720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1738ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            if (mPath.size() >= 2
1739ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1740ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // Information from the ESDS must be relied on for proper
1741ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // setup of sample rate and channel count for MPEG4 Audio.
1742ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // The generic header appears to only contain generic
1743ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // information...
1744ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1745ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1746ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        &buffer[4], chunk_data_size - 4);
1747ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1748ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                if (err != OK) {
1749ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    return err;
1750ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                }
1751ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            }
1752ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            if (mPath.size() >= 2
1753ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) {
1754ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                // Check if the video is MPEG2
1755ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                ESDS esds(&buffer[4], chunk_data_size - 4);
1756ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar
1757ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                uint8_t objectTypeIndication;
1758ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) {
1759ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) {
1760ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
1761ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    }
1762ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                }
1763ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            }
176420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
176520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
176620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
176746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        case FOURCC('b', 't', 'r', 't'):
176846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        {
176946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            *offset += chunk_size;
177046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
177146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint8_t buffer[12];
177246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (chunk_data_size != sizeof(buffer)) {
177346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                return ERROR_MALFORMED;
177446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
177546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
177646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (mDataSource->readAt(
177746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
177846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                return ERROR_IO;
177946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
178046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
178146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint32_t maxBitrate = U32_AT(&buffer[4]);
178246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint32_t avgBitrate = U32_AT(&buffer[8]);
178346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
178446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
178546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
178646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
178746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
178846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
178946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            break;
179046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        }
179146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
179220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', 'C'):
179320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
17940517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17950517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1796d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
179720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17986a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            if (buffer->data() == NULL) {
17996a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                ALOGE("b/28471206");
18006a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                return NO_MEMORY;
18016a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            }
18026a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen
180334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
1804d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1808f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1809f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1810f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
1812d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson                    kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size);
181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
181420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
181520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
18163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', 'C'):
18173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        {
18183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
18193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
18206a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            if (buffer->data() == NULL) {
18216a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                ALOGE("b/28471206");
18226a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                return NO_MEMORY;
18236a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            }
18246a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen
18253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            if (mDataSource->readAt(
18263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
18273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                return ERROR_IO;
18283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
18293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
1830f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1831f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1832f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
18333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            mLastTrack->meta->setData(
18343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                    kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size);
18353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
18363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            *offset += chunk_size;
18373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            break;
18383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
183920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1840244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        case FOURCC('d', '2', '6', '3'):
1841244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        {
18420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
184317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            /*
184417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * d263 contains a fixed 7 bytes part:
184517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   vendor - 4 bytes
184617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   version - 1 byte
184717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   level - 1 byte
184817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   profile - 1 byte
184917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * optionally, "d263" box itself may contain a 16-byte
185017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * bit rate box (bitr)
185117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   average bit rate - 4 bytes
185217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   max bit rate - 4 bytes
185317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             */
185417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            char buffer[23];
185517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            if (chunk_data_size != 7 &&
185617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong                chunk_data_size != 23) {
1857ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size);
1858244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                return ERROR_MALFORMED;
1859244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            }
1860244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1861244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            if (mDataSource->readAt(
1862244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
1863244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                return ERROR_IO;
1864244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            }
1865244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1866f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1867f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1868f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1869244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
1870244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1871244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            break;
1872244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        }
1873244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
187472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'e', 't', 'a'):
187572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
18768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            off64_t stop_offset = *offset + chunk_size;
18778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            *offset = data_offset;
18788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            bool isParsingMetaKeys = underQTMetaPath(mPath, 2);
18798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (!isParsingMetaKeys) {
18808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                uint8_t buffer[4];
18818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (chunk_data_size < (off64_t)sizeof(buffer)) {
18828ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
18838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return ERROR_MALFORMED;
18848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
1885bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
18868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (mDataSource->readAt(
18878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                            data_offset, buffer, 4) < 4) {
18888ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
18898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return ERROR_IO;
18908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
189172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
18928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (U32_AT(buffer) != 0) {
18938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // Should be version 0, flags 0.
1894ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
18958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // If it's not, let's assume this is one of those
18968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // apparently malformed chunks that don't have flags
18978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // and completely different semantics than what's
18988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // in the MPEG4 specs and skip it.
18998ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return OK;
19018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
19028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                *offset +=  sizeof(buffer);
190372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
190472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
190572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            while (*offset < stop_offset) {
190672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                status_t err = parseChunk(offset, depth + 1);
190772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
190872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
190972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
191072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
1911bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1912bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
191572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
191672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
191772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
19185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('m', 'e', 'a', 'n'):
19195d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('n', 'a', 'm', 'e'):
192072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('d', 'a', 't', 'a'):
192172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
19220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
19230517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
192472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
1925fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                status_t err = parseITunesMetaData(data_offset, chunk_data_size);
192672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
192772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
192872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
192972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
193072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
193172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
193272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
193372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
193472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
193572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'v', 'h', 'd'):
193672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
19370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
19380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1939c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 32) {
194072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_MALFORMED;
194172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
194272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
1943c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint8_t header[32];
194472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mDataSource->readAt(
194572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                        data_offset, header, sizeof(header))
194672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    < (ssize_t)sizeof(header)) {
194772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_IO;
194872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
194972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
1950fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen            uint64_t creationTime;
1951c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint64_t duration = 0;
195272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (header[0] == 1) {
195372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U64_AT(&header[4]);
1954fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                mHeaderTimescale = U32_AT(&header[20]);
1955c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = U64_AT(&header[24]);
1956c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration == 0xffffffffffffffff) {
1957c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = 0;
1958c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
1959bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (header[0] != 0) {
1960bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
196172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            } else {
196272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U32_AT(&header[4]);
1963fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                mHeaderTimescale = U32_AT(&header[12]);
1964c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                uint32_t d32 = U32_AT(&header[16]);
1965c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (d32 == 0xffffffff) {
1966c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    d32 = 0;
1967c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
1968c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = d32;
1969c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
19703724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
1971c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
197272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
197372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
197472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            String8 s;
19753724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            if (convertTimeToDate(creationTime, &s)) {
19763724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen                mFileMetaData->setCString(kKeyDate, s.string());
19773724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            }
197872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
197972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
198072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
198172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
198272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
1983c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        case FOURCC('m', 'e', 'h', 'd'):
1984c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        {
1985c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            *offset += chunk_size;
1986c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
1987c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 8) {
1988c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_MALFORMED;
1989c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
1990c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
1991c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint8_t flags[4];
1992c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (mDataSource->readAt(
1993c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                        data_offset, flags, sizeof(flags))
1994c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    < (ssize_t)sizeof(flags)) {
1995c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
1996c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
1997c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
1998c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint64_t duration = 0;
1999c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (flags[0] == 1) {
2000c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                // 64 bit
2001c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (chunk_data_size < 12) {
2002c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    return ERROR_MALFORMED;
2003c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2004c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mDataSource->getUInt64(data_offset + 4, &duration);
2005c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration == 0xffffffffffffffff) {
2006c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = 0;
2007c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2008c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            } else if (flags[0] == 0) {
2009c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                // 32 bit
2010c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                uint32_t d32;
2011c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mDataSource->getUInt32(data_offset + 4, &d32);
2012c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (d32 == 0xffffffff) {
2013c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    d32 = 0;
2014c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2015c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = d32;
2016c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            } else {
2017c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_MALFORMED;
2018c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2019c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2020e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake            if (duration != 0 && mHeaderTimescale != 0) {
2021c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
2022c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2024c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            break;
2025c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
2026c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2027dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        case FOURCC('m', 'd', 'a', 't'):
2028dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        {
2029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("mdat chunk, drm: %d", mIsDrm);
2030928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
2031928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            mMdatFound = true;
2032928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
2033dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (!mIsDrm) {
2034dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                *offset += chunk_size;
2035dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                break;
2036dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
2037dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2038dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (chunk_size < 8) {
2039dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
2040dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
2041dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2042dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return parseDrmSINF(offset, data_offset);
2043dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
2044dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
20453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        case FOURCC('h', 'd', 'l', 'r'):
20463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        {
20470517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
20480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2049ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang            if (underQTMetaPath(mPath, 3)) {
2050ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                break;
2051ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang            }
2052ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang
20533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t buffer;
20543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (mDataSource->readAt(
20553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                        data_offset + 8, &buffer, 4) < 4) {
20563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                return ERROR_IO;
20573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
20583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
20593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t type = ntohl(buffer);
20603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            // For the 3GPP file format, the handler-type within the 'hdlr' box
2061e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            // shall be 'text'. We also want to support 'sbtl' handler type
2062e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            // for a practical reason as various MPEG4 containers use it.
2063e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
2064cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                if (mLastTrack != NULL) {
2065cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                    mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
2066cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                }
20673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
20683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
20693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            break;
20703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        }
20713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
20728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        case FOURCC('k', 'e', 'y', 's'):
20738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        {
20748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            *offset += chunk_size;
20758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
20768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (underQTMetaPath(mPath, 3)) {
20778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                parseQTMetaKey(data_offset, chunk_data_size);
20788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            }
20798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            break;
20808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
20818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
2082c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        case FOURCC('t', 'r', 'e', 'x'):
2083c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        {
2084c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            *offset += chunk_size;
2085c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2086c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 24) {
2087c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2088c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2089c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            Trex trex;
2090c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) ||
2091c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) ||
2092c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) ||
2093c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) ||
2094c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) {
2095c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2096c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2097c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mTrex.add(trex);
2098c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            break;
2099c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
2100c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
21017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        case FOURCC('t', 'x', '3', 'g'):
21027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        {
2103f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
2104f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
2105f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
21063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t type;
21073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            const void *data;
21083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            size_t size = 0;
21093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (!mLastTrack->meta->findData(
21103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    kKeyTextFormatData, &type, &data, &size)) {
21113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                size = 0;
21123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21140e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich            if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
2115dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake                return ERROR_MALFORMED;
2116dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake            }
2117dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake
21188da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
21198da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (buffer == NULL) {
21208da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
21218da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
21223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (size > 0) {
21243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                memcpy(buffer, data, size);
21253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
21283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    < chunk_size) {
21293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                delete[] buffer;
21303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                buffer = NULL;
21313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21320517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen                // advance read pointer so we don't end up reading this again
21330517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen                *offset += chunk_size;
21343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                return ERROR_IO;
21353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            mLastTrack->meta->setData(
21383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    kKeyTextFormatData, 0, buffer, size + chunk_size);
21393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            delete[] buffer;
21417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
21427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            *offset += chunk_size;
21437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            break;
21447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
21457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2146515e855eae78aa495da58356486aaa666cb57fd1James Dong        case FOURCC('c', 'o', 'v', 'r'):
2147515e855eae78aa495da58356486aaa666cb57fd1James Dong        {
21480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
21490517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2150515e855eae78aa495da58356486aaa666cb57fd1James Dong            if (mFileMetaData != NULL) {
2151635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64,
2152635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                      chunk_data_size, data_offset);
21531e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake
2154635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) {
21551e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake                    return ERROR_MALFORMED;
21561e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake                }
21571552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
21586a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                if (buffer->data() == NULL) {
21596a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                    ALOGE("b/28471206");
21606a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                    return NO_MEMORY;
21616a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                }
2162515e855eae78aa495da58356486aaa666cb57fd1James Dong                if (mDataSource->readAt(
21631552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                    data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
2164515e855eae78aa495da58356486aaa666cb57fd1James Dong                    return ERROR_IO;
2165515e855eae78aa495da58356486aaa666cb57fd1James Dong                }
2166515e855eae78aa495da58356486aaa666cb57fd1James Dong                const int kSkipBytesOfDataBox = 16;
216797d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                if (chunk_data_size <= kSkipBytesOfDataBox) {
216897d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                    return ERROR_MALFORMED;
216997d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                }
217097d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake
2171515e855eae78aa495da58356486aaa666cb57fd1James Dong                mFileMetaData->setData(
2172515e855eae78aa495da58356486aaa666cb57fd1James Dong                    kKeyAlbumArt, MetaData::TYPE_NONE,
21731552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                    buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
2174515e855eae78aa495da58356486aaa666cb57fd1James Dong            }
2175515e855eae78aa495da58356486aaa666cb57fd1James Dong
2176515e855eae78aa495da58356486aaa666cb57fd1James Dong            break;
2177515e855eae78aa495da58356486aaa666cb57fd1James Dong        }
2178515e855eae78aa495da58356486aaa666cb57fd1James Dong
217958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        case FOURCC('c', 'o', 'l', 'r'):
218058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        {
218158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            *offset += chunk_size;
218258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
218358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            // ignore otherwise
218458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
218558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                status_t err = parseColorInfo(data_offset, chunk_data_size);
218658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                if (err != OK) {
218758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                    return err;
218858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                }
218958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            }
219058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
219158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            break;
219258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        }
219358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
2194fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('t', 'i', 't', 'l'):
2195fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('p', 'e', 'r', 'f'):
2196fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'u', 't', 'h'):
2197fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('g', 'n', 'r', 'e'):
2198fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'l', 'b', 'm'):
2199fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('y', 'r', 'r', 'c'):
2200fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
22010517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
22020517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2203fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
2204fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2205fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (err != OK) {
2206fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                return err;
2207fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2208fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2209fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2210fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2211fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2212328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        case FOURCC('I', 'D', '3', '2'):
2213328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        {
22140517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
22150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2216328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            if (chunk_data_size < 6) {
2217328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                return ERROR_MALFORMED;
2218328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            }
2219328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2220328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            parseID3v2MetaData(data_offset + 6);
2221328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2222328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            break;
2223328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
2224328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
22255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('-', '-', '-', '-'):
22265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        {
22275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentMean.clear();
22285d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentName.clear();
22295d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentData.clear();
22305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            *offset += chunk_size;
22315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            break;
22325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        }
22335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen
223405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('s', 'i', 'd', 'x'):
223505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        {
223605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            parseSegmentIndex(data_offset, chunk_data_size);
223705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset += chunk_size;
223805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return UNKNOWN_ERROR; // stop parsing after sidx
223905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
224005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
224120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
224220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
22438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            // check if we're parsing 'ilst' for meta keys
22448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            // if so, treat type as a number (key-id).
22458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (underQTMetaPath(mPath, 3)) {
22468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
22478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            }
22488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
224920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
225020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
225120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
225220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
225320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
225420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
225520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
225620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
225705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
225805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen  ALOGV("MPEG4Extractor::parseSegmentIndex");
225905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
226005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 12) {
226105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      return -EINVAL;
226205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
226305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
226405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
226505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) {
226605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
226705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
226805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
226905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t version = flags >> 24;
227005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    flags &= 0xffffff;
227105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
227205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("sidx version %d", version);
227305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
227405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t referenceId;
227505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
227605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
227705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
227805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
227905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t timeScale;
228005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
228105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
228205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
228305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
2284e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake    if (timeScale == 0)
2285e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake        return ERROR_MALFORMED;
228605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
228705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t earliestPresentationTime;
228805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t firstOffset;
228905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
229005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 12;
229105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 12;
229205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
229305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (version == 0) {
229405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 8) {
229505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
229605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
229705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t tmp;
229805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
229905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
230005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
230105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        earliestPresentationTime = tmp;
230205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset + 4, &tmp)) {
230305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
230405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
230505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        firstOffset = tmp;
230605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 8;
230705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 8;
230805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
230905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 16) {
231005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
231105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
231205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
231305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
231405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
231505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
231605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
231705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
231805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 16;
231905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 16;
232005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
2321a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset);
232205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
232305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 4) {
232405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
232505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
232605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
232705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint16_t referenceCount;
232805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
232905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
233005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
233105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 4;
233205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 4;
233305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("refcount: %d", referenceCount);
233405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
233505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < referenceCount * 12) {
233605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
233705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
233805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
233905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t total_duration = 0;
234005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    for (unsigned int i = 0; i < referenceCount; i++) {
234105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t d1, d2, d3;
234205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
234305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &d1) ||     // size
234405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            !mDataSource->getUInt32(offset + 4, &d2) || // duration
234505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            !mDataSource->getUInt32(offset + 8, &d3)) { // flags
234605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
234705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
234805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
234905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (d1 & 0x80000000) {
235005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGW("sub-sidx boxes not supported yet");
235105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
235205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bool sap = d3 & 0x80000000;
23533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen        uint32_t saptype = (d3 >> 28) & 7;
23543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen        if (!sap || (saptype != 1 && saptype != 2)) {
23553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            // type 1 and 2 are sync samples
23563f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            ALOGW("not a stream access point, or unsupported type: %08x", d3);
235705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
235805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        total_duration += d2;
235905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 12;
236005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
236105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        SidxEntry se;
236205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        se.mSize = d1 & 0x7fffffff;
236305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        se.mDurationUs = 1000000LL * d2 / timeScale;
236405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mSidxEntries.add(se);
236505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
236605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2367c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    uint64_t sidxDuration = total_duration * 1000000 / timeScale;
236805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2369f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
2370f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
2371f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
237205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t metaDuration;
237305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
2374c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        mLastTrack->meta->setInt64(kKeyDuration, sidxDuration);
237505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
237605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
237705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
237805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
23798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) {
23808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (size < 8) {
23818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
23828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
23838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
23848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t count;
23858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 4, &count)) {
23868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
23878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
23888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
23898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (mMetaKeyMap.size() > 0) {
23908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        ALOGW("'keys' atom seen again, discarding existing entries");
23918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        mMetaKeyMap.clear();
23928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
23938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
23948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    off64_t keyOffset = offset + 8;
23958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    off64_t stopOffset = offset + size;
23968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    for (size_t i = 1; i <= count; i++) {
23978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (keyOffset + 8 > stopOffset) {
23988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
23998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t keySize;
24028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(keyOffset, &keySize)
24038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || keySize < 8
24048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || keyOffset + keySize > stopOffset) {
24058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
24068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t type;
24098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(keyOffset + 4, &type)
24108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || type != FOURCC('m', 'd', 't', 'a')) {
24118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
24128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keySize -= 8;
24158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keyOffset += 8;
24168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24178cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        sp<ABuffer> keyData = new ABuffer(keySize);
24188cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (keyData->data() == NULL) {
24198cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
24208cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24218cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (mDataSource->readAt(
24228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                keyOffset, keyData->data(), keySize) < (ssize_t) keySize) {
24238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
24248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        AString key((const char *)keyData->data(), keySize);
24278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        mMetaKeyMap.add(i, key);
24288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keyOffset += keySize;
24308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
24318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return OK;
24328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
24338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal(
24358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        int32_t keyId, off64_t offset, size_t size) {
24368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    ssize_t index = mMetaKeyMap.indexOfKey(keyId);
24378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (index < 0) {
24388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // corresponding key is not present, ignore
24398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
24408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
244105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
24428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (size <= 16) {
24438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
24448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
24458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t dataSize;
24468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset, &dataSize)
24478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || dataSize > size || dataSize <= 16) {
24488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
24498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
24508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t atomFourCC;
24518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
24528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || atomFourCC != FOURCC('d', 'a', 't', 'a')) {
24538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
24548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
24558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t dataType;
24568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 8, &dataType)
24578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || ((dataType & 0xff000000) != 0)) {
24588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // not well-known type
24598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
24608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
24618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    dataSize -= 16;
24638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    offset += 16;
24648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (dataType == 23 && dataSize >= 4) {
24668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // BE Float32
24678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t val;
24688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(offset, &val)) {
24698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
24708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
24728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val);
24738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
24748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    } else {
24758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // add more keys if needed
24768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
24778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
24788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
24798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return OK;
24808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
248105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2482ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader(
2483c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, off64_t data_size) {
2484ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (data_size < 4) {
2485ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
2486ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2487ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2488ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t version;
2489ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(data_offset, &version, 1) < 1) {
2490ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
2491ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2492ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2493ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t dynSize = (version == 1) ? 36 : 24;
2494ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2495ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t buffer[36 + 60];
2496ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2497c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    if (data_size != (off64_t)dynSize + 60) {
2498ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
2499ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2500ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2501ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(
2502ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                data_offset, buffer, data_size) < (ssize_t)data_size) {
2503ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
2504ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2505ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2506b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    uint64_t ctime __unused, mtime __unused, duration __unused;
2507ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t id;
2508ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2509ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (version == 1) {
2510ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U64_AT(&buffer[4]);
2511ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U64_AT(&buffer[12]);
2512ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[20]);
2513ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U64_AT(&buffer[28]);
251404022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen    } else if (version == 0) {
2515ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U32_AT(&buffer[4]);
2516ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U32_AT(&buffer[8]);
2517ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[12]);
2518ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U32_AT(&buffer[20]);
251904022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen    } else {
252004022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen        return ERROR_UNSUPPORTED;
2521ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2522ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2523f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
2524f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
2525f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
2526ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    mLastTrack->meta->setInt32(kKeyTrackID, id);
2527ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2528ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t matrixOffset = dynSize + 16;
2529ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a00 = U32_AT(&buffer[matrixOffset]);
2530ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
2531ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
2532ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
2533ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2534ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0
2535b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
2536b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
2537b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe
2538df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("x' = %.2f * x + %.2f * y + %.2f",
2539ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
2540df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("y' = %.2f * x + %.2f * y + %.2f",
2541ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
2542ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif
2543ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2544ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t rotationDegrees;
2545ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2546ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    static const int32_t kFixedOne = 0x10000;
2547ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
2548ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        // Identity, no rotation
2549ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
2550ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
2551ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 90;
2552ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
2553ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 270;
2554ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
2555ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 180;
2556ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
25575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("We only support 0,90,180,270 degree rotation matrices");
2558ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
2559ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2560ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2561ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (rotationDegrees != 0) {
2562ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
2563ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2564ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2565b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    // Handle presentation display size, which could be different
2566b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    // from the image size indicated by kKeyWidth and kKeyHeight.
2567ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t width = U32_AT(&buffer[dynSize + 52]);
2568ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t height = U32_AT(&buffer[dynSize + 56]);
2569b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
2570b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
2571ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2572ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    return OK;
2573ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber}
2574ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2575fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
2576c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich    if (size < 4 || size == SIZE_MAX) {
257772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_MALFORMED;
257872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
257972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
25808da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
25818da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (buffer == NULL) {
25828da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
25838da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
258472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (mDataSource->readAt(
258572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                offset, buffer, size) != (ssize_t)size) {
258672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        delete[] buffer;
258772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        buffer = NULL;
258872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
258972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_IO;
259072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
259172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
259272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t flags = U32_AT(buffer);
259372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
259472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t metadataKey = 0;
25955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen    char chunk[5];
25965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen    MakeFourCCString(mPath[4], chunk);
2597ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("meta: %s @ %lld", chunk, (long long)offset);
25982d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer    switch ((int32_t)mPath[4]) {
259972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'a', 'l', 'b'):
260072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
260172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbum;
260272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
260372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
260472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'A', 'R', 'T'):
260572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
260672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyArtist;
260772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
260872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
260966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        case FOURCC('a', 'A', 'R', 'T'):
261066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        {
261166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            metadataKey = kKeyAlbumArtist;
261266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            break;
261366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        }
261472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'd', 'a', 'y'):
261572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
261672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyYear;
261772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
261872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
261972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'n', 'a', 'm'):
262072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
262172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyTitle;
262272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
262372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
262472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'w', 'r', 't'):
262572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
262672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyWriter;
262772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
262872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
262972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('c', 'o', 'v', 'r'):
263072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
263172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbumArt;
263272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
263372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
263472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('g', 'n', 'r', 'e'):
263572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
263672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyGenre;
263772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
263872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
263926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC(0xa9, 'g', 'e', 'n'):
264026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
264126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            metadataKey = kKeyGenre;
264226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
264326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
264411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        case FOURCC('c', 'p', 'i', 'l'):
264511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        {
264611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            if (size == 9 && flags == 21) {
264711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                char tmp[16];
264811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                sprintf(tmp, "%d",
264911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                        (int)buffer[size - 1]);
265011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen
265111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                mFileMetaData->setCString(kKeyCompilation, tmp);
265211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            }
265311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            break;
265411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        }
265572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('t', 'r', 'k', 'n'):
265672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
265772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (size == 16 && flags == 0) {
265872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char tmp[16];
2659afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTrack = (uint16_t*)&buffer[10];
2660afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
2661afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
266272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
266372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
266472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
266572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
266672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
266726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC('d', 'i', 's', 'k'):
266826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
2669afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik            if ((size == 14 || size == 16) && flags == 0) {
267026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                char tmp[16];
2671afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pDisc = (uint16_t*)&buffer[10];
2672afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
2673afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
267426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
267526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(kKeyDiscNumber, tmp);
267626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            }
267726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
267826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
26795d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('-', '-', '-', '-'):
26805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        {
26815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            buffer[size] = '\0';
26825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            switch (mPath[5]) {
26835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('m', 'e', 'a', 'n'):
26845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentMean.setTo((const char *)buffer + 4);
26855d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
26865d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('n', 'a', 'm', 'e'):
26875d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentName.setTo((const char *)buffer + 4);
26885d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
26895d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('d', 'a', 't', 'a'):
26905cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                    if (size < 8) {
26915cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        delete[] buffer;
26925cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        buffer = NULL;
26935cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        ALOGE("b/24346430");
26945cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        return ERROR_MALFORMED;
26955cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                    }
26965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentData.setTo((const char *)buffer + 8);
26975d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
26985d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            }
26998c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
27008c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // Once we have a set of mean/name/data info, go ahead and process
27018c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // it to see if its something we are interested in.  Whether or not
27028c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // were are interested in the specific tag, make sure to clear out
27038c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // the set so we can be ready to process another tuple should one
27048c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // show up later in the file.
27058c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            if ((mLastCommentMean.length() != 0) &&
27068c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                (mLastCommentName.length() != 0) &&
27078c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                (mLastCommentData.length() != 0)) {
27088c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
27098c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                if (mLastCommentMean == "com.apple.iTunes"
27108c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        && mLastCommentName == "iTunSMPB") {
27118c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    int32_t delay, padding;
27128c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    if (sscanf(mLastCommentData,
27138c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                               " %*x %x %x %*x", &delay, &padding) == 2) {
2714f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                        if (mLastTrack == NULL)
2715f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                            return ERROR_MALFORMED;
2716f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
27178c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
27188c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
27198c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    }
27205d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                }
27218c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
27225d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentMean.clear();
27235d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentName.clear();
27245d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentData.clear();
27255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            }
27265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            break;
27275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        }
272826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
272972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        default:
273072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
273172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
273272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2733328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
273472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        if (metadataKey == kKeyAlbumArt) {
273572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setData(
273672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    kKeyAlbumArt, MetaData::TYPE_NONE,
273772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    buffer + 8, size - 8);
273872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else if (metadataKey == kKeyGenre) {
273972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (flags == 0) {
274026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // uint8_t genre code, iTunes genre codes are
274126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // the standard id3 codes, except they start
274226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // at 1 instead of 0 (e.g. Pop is 14, not 13)
274326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // We use standard id3 numbering, so subtract 1.
274426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                int genrecode = (int)buffer[size - 1];
274526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                genrecode--;
274626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                if (genrecode < 0) {
274726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                    genrecode = 255; // reserved for 'unknown genre'
274826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                }
274972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char genre[10];
275026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                sprintf(genre, "%d", genrecode);
275172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
275272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(metadataKey, genre);
275326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            } else if (flags == 1) {
275426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // custom genre string
275526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                buffer[size] = '\0';
275626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
275726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(
275826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                        metadataKey, (const char *)buffer + 8);
275972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
276072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else {
276172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            buffer[size] = '\0';
276272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
276372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(
276472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    metadataKey, (const char *)buffer + 8);
276572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
276672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
276772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
276872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    delete[] buffer;
276972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    buffer = NULL;
277072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
277172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return OK;
277272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
277372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
277458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
277558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
277658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_MALFORMED;
277758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
277858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
277958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
278058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (buffer == NULL) {
278158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_MALFORMED;
278258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
278358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
278458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        delete[] buffer;
278558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        buffer = NULL;
278658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
278758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_IO;
278858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
278958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
279058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    int32_t type = U32_AT(&buffer[0]);
279158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
279258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) {
279358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t primaries = U16_AT(&buffer[4]);
279458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t transfer = U16_AT(&buffer[6]);
279558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t coeffs = U16_AT(&buffer[8]);
279658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);
279758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
279858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorAspects aspects;
279958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorUtils::convertIsoColorAspectsToCodecAspects(
280058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                primaries, transfer, coeffs, fullRange, aspects);
280158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
280258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        // only store the first color specification
280358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) {
280458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries);
280558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer);
280658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
280758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange);
280858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        }
280958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
281058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
281158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    delete[] buffer;
281258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    buffer = NULL;
281358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
281458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    return OK;
281558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar}
281658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
2817fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
28185cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake    if (size < 4 || size == SIZE_MAX) {
2819fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        return ERROR_MALFORMED;
2820fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
2821fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
28225cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
28238da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (buffer == NULL) {
28248da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
28258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
2826fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    if (mDataSource->readAt(
2827fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                offset, buffer, size) != (ssize_t)size) {
2828fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        delete[] buffer;
2829fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        buffer = NULL;
2830fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2831fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        return ERROR_IO;
2832fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
2833fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2834fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    uint32_t metadataKey = 0;
2835fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    switch (mPath[depth]) {
2836fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('t', 'i', 't', 'l'):
2837fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
2838fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyTitle;
2839fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2840fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2841fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('p', 'e', 'r', 'f'):
2842fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
2843fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyArtist;
2844fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2845fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2846fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'u', 't', 'h'):
2847fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
2848fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyWriter;
2849fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2850fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2851fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('g', 'n', 'r', 'e'):
2852fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
2853fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyGenre;
2854fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2855fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2856fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'l', 'b', 'm'):
2857fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
2858fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (buffer[size - 1] != '\0') {
2859fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              char tmp[4];
2860fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              sprintf(tmp, "%u", buffer[size - 1]);
2861fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2862fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
2863fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2864fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2865fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyAlbum;
2866fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2867fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2868fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('y', 'r', 'r', 'c'):
2869fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
2870fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            char tmp[5];
2871fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            uint16_t year = U16_AT(&buffer[4]);
2872fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2873fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (year < 10000) {
2874fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                sprintf(tmp, "%u", year);
2875fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2876fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                mFileMetaData->setCString(kKeyYear, tmp);
2877fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2878fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2879fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2880fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2881fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        default:
2882fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2883fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
2884fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2885fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    if (metadataKey > 0) {
2886fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        bool isUTF8 = true; // Common case
2887fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        char16_t *framedata = NULL;
2888fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        int len16 = 0; // Number of UTF-16 characters
2889fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2890fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
28919458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake        if (size < 6) {
28929458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake            return ERROR_MALFORMED;
28939458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake        }
28949458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake
2895fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        if (size - 6 >= 4) {
2896fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
2897fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            framedata = (char16_t *)(buffer + 6);
2898fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (0xfffe == *framedata) {
2899fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // endianness marker (BOM) doesn't match host endianness
2900fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                for (int i = 0; i < len16; i++) {
2901fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                    framedata[i] = bswap_16(framedata[i]);
2902fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                }
2903fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // BOM is now swapped to 0xfeff, we will execute next block too
2904fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2905fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2906fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (0xfeff == *framedata) {
2907fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // Remove the BOM
2908fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                framedata++;
2909fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                len16--;
2910fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                isUTF8 = false;
2911fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2912fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // else normal non-zero-length UTF-8 string
2913fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // we can't handle UTF-16 without BOM as there is no other
2914fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // indication of encoding.
2915fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2916fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2917fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        if (isUTF8) {
29185cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake            buffer[size] = 0;
2919fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            mFileMetaData->setCString(metadataKey, (const char *)buffer + 6);
2920fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        } else {
2921fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // Convert from UTF-16 string to UTF-8 string.
2922fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            String8 tmpUTF8str(framedata, len16);
2923fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            mFileMetaData->setCString(metadataKey, tmpUTF8str.string());
2924fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2925fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
2926fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2927fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    delete[] buffer;
2928fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    buffer = NULL;
2929fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2930fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    return OK;
2931fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé}
2932fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2933328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
2934328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    ID3 id3(mDataSource, true /* ignorev1 */, offset);
2935328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2936328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (id3.isValid()) {
2937328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        struct Map {
2938328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            int key;
2939328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            const char *tag1;
2940328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            const char *tag2;
2941328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        };
2942328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        static const Map kMap[] = {
2943328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAlbum, "TALB", "TAL" },
2944328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyArtist, "TPE1", "TP1" },
2945328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAlbumArtist, "TPE2", "TP2" },
2946328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyComposer, "TCOM", "TCM" },
2947328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyGenre, "TCON", "TCO" },
2948328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyTitle, "TIT2", "TT2" },
2949328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyYear, "TYE", "TYER" },
2950328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAuthor, "TXT", "TEXT" },
2951328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyCDTrackNumber, "TRK", "TRCK" },
2952328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyDiscNumber, "TPA", "TPOS" },
2953328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyCompilation, "TCP", "TCMP" },
2954328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        };
2955328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
2956328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2957328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        for (size_t i = 0; i < kNumMapEntries; ++i) {
2958328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            if (!mFileMetaData->hasData(kMap[i].key)) {
2959328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
2960328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                if (it->done()) {
2961328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    delete it;
2962328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    it = new ID3::Iterator(id3, kMap[i].tag2);
2963328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                }
2964328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2965328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                if (it->done()) {
2966328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    delete it;
2967328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    continue;
2968328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                }
2969328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2970328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                String8 s;
2971328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                it->getString(&s);
2972328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                delete it;
2973328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2974328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                mFileMetaData->setCString(kMap[i].key, s);
2975328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            }
2976328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
2977328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2978328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        size_t dataSize;
2979328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        String8 mime;
2980328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        const void *data = id3.getAlbumArt(&dataSize, &mime);
2981328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2982328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        if (data) {
2983328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
2984328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
2985328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
2986328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    }
2987328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé}
2988328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2989b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) {
299020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
299120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
2992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return NULL;
299320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
299420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
299520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
299620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
299720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
2998693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return NULL;
299920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
300020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
300120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
300220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
300320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
300420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3005371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
3006371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
3007371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
3008371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
3009c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3010c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    Trex *trex = NULL;
3011c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    int32_t trackId;
3012c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    if (track->meta->findInt32(kKeyTrackID, &trackId)) {
3013c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        for (size_t i = 0; i < mTrex.size(); i++) {
3014949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen            Trex *t = &mTrex.editItemAt(i);
3015c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (t->track_ID == (uint32_t) trackId) {
3016c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                trex = t;
3017c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                break;
3018c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
3019c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
30200386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    } else {
30210386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        ALOGE("b/21657957");
30220386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        return NULL;
3023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    }
3024c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3025a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("getTrack called, pssh: %zu", mPssh.size());
3026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3027a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    const char *mime;
3028a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    if (!track->meta->findCString(kKeyMIMEType, &mime)) {
3029a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        return NULL;
3030a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    }
3031a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3032a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3033a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        uint32_t type;
3034a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const void *data;
3035a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        size_t size;
3036a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) {
3037a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3038a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3039a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3040a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const uint8_t *ptr = (const uint8_t *)data;
3041a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3042a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
3043a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3044a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3045a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
3046a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        uint32_t type;
3047a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const void *data;
3048a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        size_t size;
3049a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) {
3050a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3051a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3052a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3053a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const uint8_t *ptr = (const uint8_t *)data;
3054a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3055a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (size < 22 || ptr[0] != 1) {  // configurationVersion == 1
3056a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3057a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3058a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    }
3059a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3060942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    return new MPEG4Source(this,
306105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            track->meta, mDataSource, track->timescale, track->sampleTable,
3062c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mSidxEntries, trex, mMoofOffset);
306320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
306420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3065bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static
3066bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) {
3067bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const char *mime;
3068bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
3069bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3070bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    uint32_t type;
3071bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const void *data;
3072bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    size_t size;
3073bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3074bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
3075bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeAVCC) {
3076bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
3077bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
30783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
30793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!track->meta->findData(kKeyHVCC, &type, &data, &size)
30803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                    || type != kTypeHVCC) {
30813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            return ERROR_MALFORMED;
30823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
3083bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
3084ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
3085bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
3086bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
3087bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeESDS) {
3088bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
3089bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
3090bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    }
3091bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3092ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih    if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
3093169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        // Make sure we have all the metadata we need.
3094ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih        ALOGE("stbl atom missing/invalid.");
3095169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        return ERROR_MALFORMED;
3096169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    }
3097169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
30982e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang    if (track->timescale == 0) {
30992e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang        ALOGE("timescale invalid.");
31002e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang        return ERROR_MALFORMED;
31012e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang    }
31022e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang
3103bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    return OK;
3104bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber}
3105bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3106f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum {
3107f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_NONE             = -1,
3108f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_NULL_OBJECT      = 0,
3109f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_MAIN         = 1, /**< Main profile                              */
3110f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_AAC_LC           = 2,   /**< Low Complexity object                     */
3111f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SSR          = 3,
3112f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_LTP          = 4,
3113f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_SBR              = 5,
3114f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SCAL         = 6,
3115f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_TWIN_VQ          = 7,
3116f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_CELP             = 8,
3117f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_HVXC             = 9,
3118f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_10          = 10, /**< (reserved)                                */
3119f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_11          = 11, /**< (reserved)                                */
3120f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_TTSI             = 12, /**< TTSI Object                               */
3121f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MAIN_SYNTH       = 13, /**< Main Synthetic object                     */
3122f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_WAV_TAB_SYNTH    = 14, /**< Wavetable Synthesis object                */
3123f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_GEN_MIDI         = 15, /**< General MIDI object                       */
3124f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
3125f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_LC        = 17,   /**< Error Resilient(ER) AAC Low Complexity    */
3126f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_18          = 18, /**< (reserved)                                */
3127f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_AAC_LTP       = 19, /**< Error Resilient(ER) AAC LTP object        */
3128f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_SCAL      = 20,   /**< Error Resilient(ER) AAC Scalable object   */
3129f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_TWIN_VQ       = 21, /**< Error Resilient(ER) TwinVQ object         */
3130f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_BSAC          = 22,   /**< Error Resilient(ER) BSAC object           */
3131f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_LD        = 23,   /**< Error Resilient(ER) AAC LowDelay object   */
3132f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_CELP          = 24, /**< Error Resilient(ER) CELP object           */
3133f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_HVXC          = 25, /**< Error Resilient(ER) HVXC object           */
3134f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_HILN          = 26, /**< Error Resilient(ER) HILN object           */
3135f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_PARA          = 27, /**< Error Resilient(ER) Parametric object     */
3136f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_28          = 28, /**< might become SSC                          */
3137f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_PS               = 29,   /**< PS, Parametric Stereo (includes SBR)      */
3138f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MPEGS            = 30, /**< MPEG Surround                             */
3139f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3140f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ESCAPE           = 31,   /**< Signal AOT uses more than 5 bits          */
3141f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3142f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L1      = 32, /**< MPEG-Layer1 in mp4                        */
3143f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L2      = 33, /**< MPEG-Layer2 in mp4                        */
3144f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L3      = 34, /**< MPEG-Layer3 in mp4                        */
3145f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_35          = 35, /**< might become DST                          */
3146f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_36          = 36, /**< might become ALS                          */
3147f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SLS          = 37, /**< AAC + SLS                                 */
3148f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_SLS              = 38, /**< SLS                                       */
3149f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_AAC_ELD       = 39, /**< AAC Enhanced Low Delay                    */
3150f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3151f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_USAC             = 42, /**< USAC                                      */
3152f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_SAOC             = 43, /**< SAOC                                      */
3153f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_LD_MPEGS         = 44, /**< Low Delay MPEG Surround                   */
3154f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3155f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD50           = 50,  /**< Interim AOT for Rsvd50                   */
3156f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE;
3157f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3158ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
3159ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        const void *esds_data, size_t esds_size) {
3160ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    ESDS esds(esds_data, esds_size);
316181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
316281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    uint8_t objectTypeIndication;
316381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
316481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return ERROR_MALFORMED;
316581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
316681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
316781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (objectTypeIndication == 0xe1) {
316881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // This isn't MPEG4 audio at all, it's QCELP 14k...
3169f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        if (mLastTrack == NULL)
3170f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            return ERROR_MALFORMED;
3171f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
317281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
317381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return OK;
317481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
317581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
3176633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong    if (objectTypeIndication  == 0x6b) {
3177633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // The media subtype is MP3 audio
3178633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // Our software MP3 audio decoder may not be able to handle
3179633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
318029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("MP3 track in MP4/3GPP file is not supported");
3181633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        return ERROR_UNSUPPORTED;
3182633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong    }
3183633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong
3184ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    const uint8_t *csd;
3185ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    size_t csd_size;
3186ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (esds.getCodecSpecificInfo(
3187ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                (const void **)&csd, &csd_size) != OK) {
3188ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
3189ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3190ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3191b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    if (kUseHexDump) {
3192ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        printf("ESD of size %zu\n", csd_size);
3193b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        hexdump(csd, csd_size);
3194b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    }
3195ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3196a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    if (csd_size == 0) {
3197a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // There's no further information, i.e. no codec specific data
3198a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // Let's assume that the information provided in the mpeg4 headers
3199a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // is accurate and hope for the best.
3200a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
3201a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        return OK;
3202a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    }
3203a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
3204ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (csd_size < 2) {
3205ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
3206ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3207ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
320800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    static uint32_t kSamplingRate[] = {
320900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
321000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        16000, 12000, 11025, 8000, 7350
321100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    };
321200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent
3213aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    ABitReader br(csd, csd_size);
3214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    uint32_t objectType = br.getBits(5);
3215ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3216aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (objectType == 31) {  // AAC-ELD => additional 6 bits
3217aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        objectType = 32 + br.getBits(6);
3218ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3219ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3220f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
3221f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
3222f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
3223db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    //keep AOT type
3224db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
3225db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
3226aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    uint32_t freqIndex = br.getBits(4);
3227aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
3228ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t sampleRate = 0;
3229ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t numChannels = 0;
3230ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (freqIndex == 15) {
32318e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
3232aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        sampleRate = br.getBits(24);
3233aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        numChannels = br.getBits(4);
3234ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    } else {
32358e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3236595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen        numChannels = br.getBits(4);
323700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent
323800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        if (freqIndex == 13 || freqIndex == 14) {
323900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            return ERROR_MALFORMED;
3240ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        }
3241ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
324200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        sampleRate = kSamplingRate[freqIndex];
324300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    }
3244595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen
3245f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
32468e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
324700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        uint32_t extFreqIndex = br.getBits(4);
3248b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        int32_t extSampleRate __unused;
324900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        if (extFreqIndex == 15) {
325000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            if (csd_size < 8) {
3251595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen                return ERROR_MALFORMED;
3252595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen            }
32538e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
325400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            extSampleRate = br.getBits(24);
325500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        } else {
325600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            if (extFreqIndex == 13 || extFreqIndex == 14) {
325700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent                return ERROR_MALFORMED;
325800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            }
325900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            extSampleRate = kSamplingRate[extFreqIndex];
3260595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen        }
326100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        //TODO: save the extension sampling rate value in meta data =>
326200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        //      mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
3263ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3264ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3265f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    switch (numChannels) {
3266f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
3267f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 0:
3268f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 1:// FC
3269f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 2:// FL FR
3270f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 3:// FC, FL FR
3271f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 4:// FC, FL FR, RC
3272f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 5:// FC, FL FR, SL SR
3273f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 6:// FC, FL FR, SL SR, LFE
3274f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            //numChannels already contains the right value
3275f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3276f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 11:// FC, FL FR, SL SR, RC, LFE
3277f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            numChannels = 7;
3278f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3279f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 7: // FC, FCL FCR, FL FR, SL SR, LFE
3280f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 12:// FC, FL  FR,  SL SR, RL RR, LFE
3281f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 14:// FC, FL  FR,  SL SR, LFE, FHL FHR
3282f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            numChannels = 8;
3283f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3284f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        default:
3285f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            return ERROR_UNSUPPORTED;
3286f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    }
3287f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3288f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    {
3289f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        if (objectType == AOT_SBR || objectType == AOT_PS) {
32908e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3291f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            objectType = br.getBits(5);
3292f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3293f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            if (objectType == AOT_ESCAPE) {
32948e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
3295f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType = 32 + br.getBits(6);
3296f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3297f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        }
3298f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
3299f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
3300f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType == AOT_ER_BSAC) {
33018e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
3302b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            const int32_t frameLengthFlag __unused = br.getBits(1);
3303f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3304f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            const int32_t dependsOnCoreCoder = br.getBits(1);
3305f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3306f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            if (dependsOnCoreCoder ) {
33078e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
3308b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t coreCoderDelay __unused = br.getBits(14);
3309f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3310f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
331145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            int32_t extensionFlag = -1;
331245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            if (br.numBitsLeft() > 0) {
331345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                extensionFlag = br.getBits(1);
331445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            } else {
331545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                switch (objectType) {
331645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                // 14496-3 4.5.1.1 extensionFlag
331745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_AAC_LC:
331845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    extensionFlag = 0;
331945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
332045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_LC:
332145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_SCAL:
332245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_BSAC:
332345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_LD:
332445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    extensionFlag = 1;
332545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
332645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                default:
33278e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    return ERROR_MALFORMED;
332845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
332945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                }
333045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                ALOGW("csd missing extension flag; assuming %d for object type %u.",
333145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                        extensionFlag, objectType);
333245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            }
3333f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
333445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            if (numChannels == 0) {
3335f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int32_t channelsEffectiveNum = 0;
3336f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int32_t channelsNum = 0;
33378e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 32) {
33388e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    return ERROR_MALFORMED;
33398e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                }
3340b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t ElementInstanceTag __unused = br.getBits(4);
3341b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t Profile __unused = br.getBits(2);
3342b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
3343f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumFrontChannelElements = br.getBits(4);
3344f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumSideChannelElements = br.getBits(4);
3345f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumBackChannelElements = br.getBits(4);
3346f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumLfeChannelElements = br.getBits(2);
3347b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t NumAssocDataElements __unused = br.getBits(3);
3348b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t NumValidCcElements __unused = br.getBits(4);
3349f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3350f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t MonoMixdownPresent = br.getBits(1);
33518e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen
3352f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (MonoMixdownPresent != 0) {
33538e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3354b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
3355f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3356f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
33578e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3358f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t StereoMixdownPresent = br.getBits(1);
3359f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (StereoMixdownPresent != 0) {
33608e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3361b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
3362f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3363f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
33648e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3365f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t MatrixMixdownIndexPresent = br.getBits(1);
3366f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (MatrixMixdownIndexPresent != 0) {
33678e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
3368b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t MatrixMixdownIndex __unused = br.getBits(2);
3369b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t PseudoSurroundEnable __unused = br.getBits(1);
3370f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3371f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3372f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int i;
3373f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumFrontChannelElements; i++) {
33748e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3375f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t FrontElementIsCpe = br.getBits(1);
3376b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t FrontElementTagSelect __unused = br.getBits(4);
3377f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += FrontElementIsCpe ? 2 : 1;
3378f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3379f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3380f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumSideChannelElements; i++) {
33818e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3382f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t SideElementIsCpe = br.getBits(1);
3383b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t SideElementTagSelect __unused = br.getBits(4);
3384f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += SideElementIsCpe ? 2 : 1;
3385f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3386f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3387f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumBackChannelElements; i++) {
33888e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3389f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t BackElementIsCpe = br.getBits(1);
3390b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t BackElementTagSelect __unused = br.getBits(4);
3391f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += BackElementIsCpe ? 2 : 1;
3392f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3393f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                channelsEffectiveNum = channelsNum;
3394f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3395f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumLfeChannelElements; i++) {
33968e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3397b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t LfeElementTagSelect __unused = br.getBits(4);
3398f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += 1;
3399f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3400f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
3401f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
3402f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                numChannels = channelsNum;
3403f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3404f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        }
3405f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    }
3406f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3407ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (numChannels == 0) {
3408ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_UNSUPPORTED;
3409ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3410ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3411f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
3412f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
3413f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
3414ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevSampleRate;
3415ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
3416ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3417ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevSampleRate != sampleRate) {
34183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("mpeg4 audio sample rate different from previous setting. "
3419ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevSampleRate, sampleRate);
3420ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3421ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3422ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
3423ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3424ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevChannelCount;
3425ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
3426ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3427ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevChannelCount != numChannels) {
34283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("mpeg4 audio channel count different from previous setting. "
3429ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevChannelCount, numChannels);
3430ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3431ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3432ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
3433ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3434ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    return OK;
3435ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber}
3436ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
343720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
343820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
343920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source(
3440942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen        const sp<MPEG4Extractor> &owner,
344120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const sp<MetaData> &format,
3442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &dataSource,
344348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        int32_t timeScale,
344405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const sp<SampleTable> &sampleTable,
344505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        Vector<SidxEntry> &sidx,
3446c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        const Trex *trex,
344705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t firstMoofOffset)
3448942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    : mOwner(owner),
3449942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen      mFormat(format),
345020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDataSource(dataSource),
345148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber      mTimescale(timeScale),
345220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleTable(sampleTable),
345320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mCurrentSampleIndex(0),
345405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentFragmentIndex(0),
345505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mSegments(sidx),
3456c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen      mTrex(trex),
345705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mFirstMoofOffset(firstMoofOffset),
345805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentMoofOffset(firstMoofOffset),
345905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentTime(0),
3460ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoAllocSize(0),
3461ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoSizes(NULL),
3462ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoOffsetsAllocSize(0),
3463ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoOffsets(NULL),
346420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mIsAVC(false),
34653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar      mIsHEVC(false),
34666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber      mNALLengthSize(0),
346720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStarted(false),
346820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mGroup(NULL),
346920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mBuffer(NULL),
3470dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber      mWantsNALFragments(false),
34710024245e134467d120b40099da16c467dc365e76Andreas Huber      mSrcBuffer(NULL) {
3472ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3473c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
3474c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3475ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
347648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    mDefaultIVSize = 0;
3477ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
3478ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t keytype;
3479ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    const void *key;
3480ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    size_t keysize;
3481ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
3482ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        CHECK(keysize <= 16);
3483ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memset(mCryptoKey, 0, 16);
3484ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memcpy(mCryptoKey, key, keysize);
3485ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3486ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
348720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
348820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = mFormat->findCString(kKeyMIMEType, &mime);
3489dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(success);
349020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
349118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
34923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
34936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
34946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    if (mIsAVC) {
34956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        uint32_t type;
34966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const void *data;
34976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t size;
34986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
34996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
35006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const uint8_t *ptr = (const uint8_t *)data;
35016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
35026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(size >= 7);
3503ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
35046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
35056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        // The number of bytes used to encode the length of a NAL unit.
35066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        mNALLengthSize = 1 + (ptr[4] & 3);
35073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (mIsHEVC) {
35083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        uint32_t type;
35093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const void *data;
35103b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t size;
35113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        CHECK(format->findData(kKeyHVCC, &type, &data, &size));
35123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
35133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
35143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3515a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        CHECK(size >= 22);
35163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
35173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
35183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        mNALLengthSize = 1 + (ptr[14 + 7] & 3);
35196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
352005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
352105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    CHECK(format->findInt32(kKeyTrackID, &mTrackId));
352205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
352305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mFirstMoofOffset != 0) {
352405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t offset = mFirstMoofOffset;
352505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        parseChunk(&offset);
352605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
352720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
352820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
352920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() {
353020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
353120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        stop();
353220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
3533ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    free(mCurrentSampleInfoSizes);
3534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    free(mCurrentSampleInfoOffsets);
353520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
353620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
353720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) {
35387b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
35397b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
3540dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(!mStarted);
354120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
354220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t val;
3543dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (params && params->findInt32(kKeyWantsNALFragments, &val)
354420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        && val != 0) {
3545dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = true;
354620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
3547dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = false;
354820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
354920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3550afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    int32_t tmp;
3551afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp));
3552afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    size_t max_size = tmp;
355320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3554afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    // A somewhat arbitrary limit that should be sufficient for 8k video frames
3555afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    // If you see the message below for a valid input stream: increase the limit
3556afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    if (max_size > 64 * 1024 * 1024) {
3557afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        ALOGE("bogus max input size: %zu", max_size);
3558afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        return ERROR_MALFORMED;
3559afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    }
3560afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    mGroup = new MediaBufferGroup;
3561738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    mGroup->add_buffer(new MediaBuffer(max_size));
35620024245e134467d120b40099da16c467dc365e76Andreas Huber
35638da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    mSrcBuffer = new (std::nothrow) uint8_t[max_size];
35648da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (mSrcBuffer == NULL) {
35658da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        // file probably specified a bad max size
3566afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        delete mGroup;
3567afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        mGroup = NULL;
35688da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
35698da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
357020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
357120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = true;
357220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
357320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
357420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
357520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
357620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() {
35777b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
35787b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
3579dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
358020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
358120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mBuffer != NULL) {
358220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->release();
358320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
358420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
358520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35860024245e134467d120b40099da16c467dc365e76Andreas Huber    delete[] mSrcBuffer;
35870024245e134467d120b40099da16c467dc365e76Andreas Huber    mSrcBuffer = NULL;
35880024245e134467d120b40099da16c467dc365e76Andreas Huber
358920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete mGroup;
359020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mGroup = NULL;
359120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
359220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = false;
359320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCurrentSampleIndex = 0;
359420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
359520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
359620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
359720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
359805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) {
359905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t hdr[2];
360005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
360105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_IO;
360205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
360305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t chunk_size = ntohl(hdr[0]);
360405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t chunk_type = ntohl(hdr[1]);
360505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t data_offset = *offset + 8;
360605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
360705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (chunk_size == 1) {
360805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
360905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_IO;
361005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
361105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        chunk_size = ntoh64(chunk_size);
361205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        data_offset += 8;
361305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (chunk_size < 16) {
361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            // The smallest valid chunk is 16 bytes long in this case.
361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (chunk_size < 8) {
361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // The smallest valid chunk is 8 bytes long.
362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
362205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    char chunk[5];
362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    MakeFourCCString(chunk_type, chunk);
3625ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t chunk_data_size = *offset + chunk_size - data_offset;
362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    switch(chunk_type) {
363005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
363105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'r', 'a', 'f'):
363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('m', 'o', 'o', 'f'): {
363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            off64_t stop_offset = *offset + chunk_size;
363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset = data_offset;
363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            while (*offset < stop_offset) {
363605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err = parseChunk(offset);
363705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (err != OK) {
363805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return err;
363905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
364005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
364105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
36423f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                // *offset points to the box following this moof. Find the next moof from there.
36433f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen
36443f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                while (true) {
36453f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
36463f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        return ERROR_END_OF_STREAM;
36473f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    }
36483f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    chunk_size = ntohl(hdr[0]);
36493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    chunk_type = ntohl(hdr[1]);
36503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
36513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        mNextMoofOffset = *offset;
36523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        break;
36533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    }
36543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    *offset += chunk_size;
36553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                }
365605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
365705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            break;
365805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
365905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
366005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'f', 'h', 'd'): {
366105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err;
366205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
366305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return err;
366405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
366505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                *offset += chunk_size;
366605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                break;
366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'r', 'u', 'n'): {
367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err;
367105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (mLastParsedTrackId == mTrackId) {
367205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
367305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        return err;
367405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    }
367505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
367605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                *offset += chunk_size;
367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                break;
367905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
3681ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'a', 'i', 'z'): {
3682ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            status_t err;
3683ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
3684ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return err;
3685ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3686ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3687ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3688ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3689ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'a', 'i', 'o'): {
3690ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            status_t err;
3691ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
3692ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return err;
3693ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3694ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3695ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3696ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3697ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3698ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('m', 'd', 'a', 't'): {
3699ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // parse DRM info if present
3700ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("MPEG4Source::parseChunk mdat");
3701ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // if saiz/saoi was previously observed, do something with the sampleinfos
3702ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3703ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3704ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3705ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
370605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        default: {
370705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset += chunk_size;
370805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            break;
370905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
371005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
371105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
371205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
371305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
371484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
371584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t offset, off64_t /* size */) {
3716ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    ALOGV("parseSampleAuxiliaryInformationSizes");
3717ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // 14496-12 8.7.12
3718ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t version;
3719ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(
3720ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset, &version, sizeof(version))
3721ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            < (ssize_t)sizeof(version)) {
3722ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3723ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3724ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3725ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (version != 0) {
3726ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_UNSUPPORTED;
3727ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3728ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
3729ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3730ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t flags;
3731ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt24(offset, &flags)) {
3732ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 3;
3735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3736ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (flags & 1) {
3737ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        uint32_t tmp;
3738ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
3739ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_MALFORMED;
3740ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3741ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentAuxInfoType = tmp;
3742ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        offset += 4;
3743ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
3744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_MALFORMED;
3745ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3746ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentAuxInfoTypeParameter = tmp;
3747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        offset += 4;
3748ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t defsize;
3751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(offset, &defsize, 1) != 1) {
3752ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_MALFORMED;
3753ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3754ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mCurrentDefaultSampleInfoSize = defsize;
3755ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
3756ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3757ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t smplcnt;
3758ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &smplcnt)) {
3759ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_MALFORMED;
3760ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
376148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    mCurrentSampleInfoCount = smplcnt;
3762ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 4;
3763ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
376448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (mCurrentDefaultSampleInfoSize != 0) {
376548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
376648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return OK;
376748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
3768ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (smplcnt > mCurrentSampleInfoAllocSize) {
3769ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
3770ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoAllocSize = smplcnt;
3771ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3772ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3773ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
3774ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
3775ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
3776ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
377784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
377884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t offset, off64_t /* size */) {
3779ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    ALOGV("parseSampleAuxiliaryInformationOffsets");
3780ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // 14496-12 8.7.13
3781ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t version;
3782ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
3783ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3784ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3785ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
3786ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3787ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t flags;
3788ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt24(offset, &flags)) {
3789ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3790ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3791ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 3;
3792ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3793ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t entrycount;
3794ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &entrycount)) {
3795ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3796ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3797ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 4;
3798c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (entrycount == 0) {
3799c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return OK;
3800c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
3801c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (entrycount > UINT32_MAX / 8) {
3802c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return ERROR_MALFORMED;
3803c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
3804ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3805ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
3806c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
3807c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        if (newPtr == NULL) {
3808c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia            return NO_MEMORY;
3809c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        }
3810c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        mCurrentSampleInfoOffsets = newPtr;
3811ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoOffsetsAllocSize = entrycount;
3812ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3813ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mCurrentSampleInfoOffsetCount = entrycount;
3814ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3815c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (mCurrentSampleInfoOffsets == NULL) {
3816c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return OK;
3817c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
3818c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia
3819ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < entrycount; i++) {
3820ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (version == 0) {
3821ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t tmp;
3822ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (!mDataSource->getUInt32(offset, &tmp)) {
3823ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
3824ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3825ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mCurrentSampleInfoOffsets[i] = tmp;
3826ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset += 4;
3827ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        } else {
3828ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint64_t tmp;
3829ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (!mDataSource->getUInt64(offset, &tmp)) {
3830ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
3831ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3832ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mCurrentSampleInfoOffsets[i] = tmp;
3833ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset += 8;
3834ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3835ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3836ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3837ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // parse clear/encrypted data
3838ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3839ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
3840ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3841ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    drmoffset += mCurrentMoofOffset;
3842ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int ivlength;
3843ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
384448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
3845529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    // only 0, 8 and 16 byte initialization vectors are supported
3846529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
3847529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        ALOGW("unsupported IV length: %d", ivlength);
3848529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        return ERROR_MALFORMED;
3849529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    }
385048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    // read CencSampleAuxiliaryDataFormats
3851ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
3852529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        if (i >= mCurrentSamples.size()) {
3853529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen            ALOGW("too few samples");
3854529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen            break;
3855529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        }
3856ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Sample *smpl = &mCurrentSamples.editItemAt(i);
3857ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3858ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memset(smpl->iv, 0, 16);
3859ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) {
3860ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_IO;
3861ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3862ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3863ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        drmoffset += ivlength;
3864ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
386548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
386648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        if (smplinfosize == 0) {
386748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smplinfosize = mCurrentSampleInfoSizes[i];
3868ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
386948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        if (smplinfosize > ivlength) {
387048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint16_t numsubsamples;
387148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
3872ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
3873ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3874ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            drmoffset += 2;
387548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            for (size_t j = 0; j < numsubsamples; j++) {
387648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                uint16_t numclear;
387748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                uint32_t numencrypted;
387848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                if (!mDataSource->getUInt16(drmoffset, &numclear)) {
387948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                    return ERROR_IO;
388048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                }
388148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                drmoffset += 2;
388248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
388348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                    return ERROR_IO;
388448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                }
388548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                drmoffset += 4;
388648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->clearsizes.add(numclear);
388748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->encryptedsizes.add(numencrypted);
3888ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
388948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        } else {
389048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smpl->clearsizes.add(0);
389148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smpl->encryptedsizes.add(smpl->size);
3892ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3893ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3894ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3895ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3896ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
3897ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
3898ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
389905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
390005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
390105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 8) {
390205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
390305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
390405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
3906ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
390805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
390905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & 0xff000000) {
391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
391705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mLastParsedTrackId != mTrackId) {
391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // this is not the right track, skip it
392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mFlags = flags;
392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
392505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 8;
392605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 8;
392705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
392805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
392905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
393005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
393105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 8) {
393205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
393305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
393405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
393505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
393605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
393705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
393805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 8;
393905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 8;
394005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
394105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
394205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
394705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
394805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
394905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
395005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
395105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
395205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
395305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
395405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
395505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
395605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
395705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
395805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
395905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
396005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
398505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
398605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
398705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
398805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
398905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
399005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
399105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
399205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
399305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
399405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mDataOffset = 0;
399505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
399605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
399705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
399805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
399905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
400005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("MPEG4Extractor::parseTrackFragmentRun");
400105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 8) {
400205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
400305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
400405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
400505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    enum {
400605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kDataOffsetPresent                  = 0x01,
400705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kFirstSampleFlagsPresent            = 0x04,
400805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleDurationPresent              = 0x100,
400905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleSizePresent                  = 0x200,
401005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleFlagsPresent                 = 0x400,
401105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleCompositionTimeOffsetPresent = 0x800,
401205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
401305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
401405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
401505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) {
401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("fragment run flags: %08x", flags);
401905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
402005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & 0xff000000) {
402105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
402205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
402305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
402405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
402505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // These two shall not be used together.
402605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
402705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
402805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
402905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t sampleCount;
403005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
403105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
403205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
403305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 8;
403405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 8;
403505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
403605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
403705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
403805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t firstSampleFlags = 0;
403905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
404005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kDataOffsetPresent) {
404105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
404205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
404305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
404405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
404505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int32_t dataOffsetDelta;
404605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) {
404705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
404805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
404905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
405005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
405105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
405205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
405305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
405405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
405505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
405605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kFirstSampleFlagsPresent) {
405705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
405805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
405905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
406005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
406105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
406205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
406305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
406405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
406505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
406605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
406705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
406805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
406905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen             sampleCtsOffset = 0;
407005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
407105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size_t bytesPerSample = 0;
407205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleDurationPresent) {
407305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
407405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
407505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
407605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
4077c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    } else if (mTrex) {
4078c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        sampleDuration = mTrex->default_sample_duration;
407905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
408005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
408105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleSizePresent) {
408205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
408305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
408405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
408505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
408605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
408705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
408805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
408905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
409005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleFlagsPresent) {
409105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
409205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
409305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
409405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
409505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
409605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
409705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
409805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
409905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleCompositionTimeOffsetPresent) {
410005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
410105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
410205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleCtsOffset = 0;
410305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
410405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4105ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (size < (off64_t)(sampleCount * bytesPerSample)) {
410605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
410705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
410805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
410905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Sample tmp;
411005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    for (uint32_t i = 0; i < sampleCount; ++i) {
411105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleDurationPresent) {
411205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleDuration)) {
411305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
411405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
411505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
411605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
411705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
411805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleSizePresent) {
411905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleSize)) {
412005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
412105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
412205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
412305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
412405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
412505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleFlagsPresent) {
412605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleFlags)) {
412705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
412805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
412905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
413005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
413105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
413205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleCompositionTimeOffsetPresent) {
413305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
413405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
413505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
413605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
413705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
413805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4139a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
4140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen              " flags 0x%08x", i + 1,
414105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dataOffset, sampleSize, sampleDuration,
414205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                (flags & kFirstSampleFlagsPresent) && i == 0
414305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    ? firstSampleFlags : sampleFlags);
414405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.offset = dataOffset;
414505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.size = sampleSize;
414605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.duration = sampleDuration;
4147c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        tmp.compositionOffset = sampleCtsOffset;
414805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mCurrentSamples.add(tmp);
414905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
415005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        dataOffset += sampleSize;
415105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
415205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
415305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
415405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
415505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
415605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
415705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
415820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() {
41597b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
41607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
416120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mFormat;
416220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
416320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
41646064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const {
41656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    switch (mNALLengthSize) {
41666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 1:
41676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return *data;
41686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 2:
41696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U16_AT(data);
41706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 3:
41716064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
41726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 4:
41736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U32_AT(data);
41746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
41756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
41766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // This cannot happen, mNALLengthSize springs to life by adding 1 to
41776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // a 2-bit integer.
41786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    CHECK(!"Should not be here.");
41796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
41806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    return 0;
41816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber}
41826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
418320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read(
418420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
41857b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
41867b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
4187dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
418820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
418905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mFirstMoofOffset > 0) {
419005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return fragmentedRead(out, options);
419105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
419205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
419320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *out = NULL;
419420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4195abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    int64_t targetSampleTimeUs = -1;
4196abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
419720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int64_t seekTimeUs;
4198abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
4199abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4200abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t findFlags = 0;
4201abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        switch (mode) {
4202abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_PREVIOUS_SYNC:
4203abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagBefore;
4204abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4205abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_NEXT_SYNC:
4206abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagAfter;
4207abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4208abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST_SYNC:
4209abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST:
4210abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagClosest;
4211abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4212abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            default:
4213abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(!"Should not be here.");
4214abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4215abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4216abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
421720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t sampleIndex;
4218abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleTable->findSampleAtTime(
4219599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                seekTimeUs, 1000000, mTimescale,
4220abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                &sampleIndex, findFlags);
4221abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4222abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
4223abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // We found the closest sample already, now we want the sync
4224abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // sample preceding it (or the sample itself of course), even
4225abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // if the subsequent sync sample is closer.
4226abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            findFlags = SampleTable::kFlagBefore;
4227abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4228abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4229abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleIndex;
4230abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err == OK) {
4231abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            err = mSampleTable->findSyncSampleNear(
4232abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    sampleIndex, &syncSampleIndex, findFlags);
4233abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
423420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4235788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        uint32_t sampleTime;
4236788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        if (err == OK) {
4237788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber            err = mSampleTable->getMetaDataForSample(
4238788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber                    sampleIndex, NULL, NULL, &sampleTime);
4239788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        }
4240788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber
424120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
42425295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            if (err == ERROR_OUT_OF_RANGE) {
42435295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // An attempt to seek past the end of the stream would
42445295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
42455295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // this all the way to the MediaPlayer would cause abnormal
42465295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // termination. Legacy behaviour appears to be to behave as if
42475295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // we had seeked to the end of stream, ending normally.
42485295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                err = ERROR_END_OF_STREAM;
42495295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            }
425005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGV("end of stream");
425120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
425220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
425320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4254abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
4255abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
4256abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4257abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4258abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0
4259abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleTime;
4260abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
4261abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    syncSampleIndex, NULL, NULL, &syncSampleTime));
4262abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4263df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("seek to time %lld us => sample at time %lld us, "
4264abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             "sync sample at time %lld us",
4265abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             seekTimeUs,
4266abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             sampleTime * 1000000ll / mTimescale,
4267abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             syncSampleTime * 1000000ll / mTimescale);
4268abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif
4269abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4270abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        mCurrentSampleIndex = syncSampleIndex;
427120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mBuffer != NULL) {
427220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
427320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
427420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
427520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
427620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // fall through
427720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
427820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4279c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset;
42800024245e134467d120b40099da16c467dc365e76Andreas Huber    size_t size;
4281170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    uint32_t cts, stts;
42828bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    bool isSyncSample;
4283dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool newBuffer = false;
4284dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mBuffer == NULL) {
4285dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        newBuffer = true;
428620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err =
4288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mSampleTable->getMetaDataForSample(
4289170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
429020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4291dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
4292dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
4293dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4294dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4295dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        err = mGroup->acquire_buffer(&mBuffer);
4296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
4297dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
4298ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            CHECK(mBuffer == NULL);
4299dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
4300dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4301c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        if (size > mBuffer->size()) {
4302c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4303c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            return ERROR_BUFFER_TOO_SMALL;
4304c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        }
43050024245e134467d120b40099da16c467dc365e76Andreas Huber    }
430620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
4308dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (newBuffer) {
4309dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ssize_t num_bytes_read =
431034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4311dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4312dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            if (num_bytes_read < (ssize_t)size) {
4313dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer->release();
4314dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer = NULL;
4315dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4316dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                return ERROR_IO;
4317dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            }
4318dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
43197b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber            CHECK(mBuffer != NULL);
4320dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->set_range(0, size);
4321dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->meta_data()->clear();
432248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            mBuffer->meta_data()->setInt64(
43234678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4324170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            mBuffer->meta_data()->setInt64(
4325170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4326abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4327abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (targetSampleTimeUs >= 0) {
4328abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                mBuffer->meta_data()->setInt64(
4329abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                        kKeyTargetTime, targetSampleTimeUs);
4330abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
4331abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
43328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (isSyncSample) {
43338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
43348bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
43358bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4336dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ++mCurrentSampleIndex;
4337dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4338dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
43393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!mIsAVC && !mIsHEVC) {
4340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            *out = mBuffer;
4341dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
4342dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4343dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return OK;
4344dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4345dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4346dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Each NAL unit is split up into its constituent fragments and
4347dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // each one of them returned in its own buffer.
4348dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
43496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize);
4350dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4351dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        const uint8_t *src =
4352dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
4353dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
43546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t nal_size = parseNALSize(src);
43555d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mNALLengthSize > SIZE_MAX - nal_size) {
43565d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen            ALOGE("b/24441553, b/24445122");
43575d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        }
43585d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
435929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("incomplete NAL unit.");
4360e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4361e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer->release();
4362e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer = NULL;
4363e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4364e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            return ERROR_MALFORMED;
4365e8a084958c27327b0aca749f69095605d2a21309Andreas Huber        }
4366dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4367dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        MediaBuffer *clone = mBuffer->clone();
43687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(clone != NULL);
43696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
4370dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
43717b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(mBuffer != NULL);
4372dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mBuffer->set_range(
43736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_offset() + mNALLengthSize + nal_size,
43746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_length() - mNALLengthSize - nal_size);
4375dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4376dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (mBuffer->range_length() == 0) {
4377dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->release();
4378dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
4379dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4380dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4381dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        *out = clone;
4382dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4383dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        return OK;
4384dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    } else {
4385dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Whole NAL units are returned but each fragment is prefixed by
4386dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // the start code (0x00 00 00 01).
4387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        ssize_t num_bytes_read = 0;
4388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t drm = 0;
4389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
4390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
4391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read =
4392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
4393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
4394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
4395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
439620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
439720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (num_bytes_read < (ssize_t)size) {
439820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
439920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
440020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4401dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return ERROR_IO;
440220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
440320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
4405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
4406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, size);
44076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
4408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
4409dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t *dstData = (uint8_t *)mBuffer->data();
4410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t srcOffset = 0;
4411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t dstOffset = 0;
4412e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (srcOffset < size) {
4414bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
441534fe252c89e33572d01fea981b58d7b115e76164James Dong                size_t nalLength = 0;
441634fe252c89e33572d01fea981b58d7b115e76164James Dong                if (!isMalFormed) {
441734fe252c89e33572d01fea981b58d7b115e76164James Dong                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
441834fe252c89e33572d01fea981b58d7b115e76164James Dong                    srcOffset += mNALLengthSize;
4419bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
442034fe252c89e33572d01fea981b58d7b115e76164James Dong                }
4421e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
442234fe252c89e33572d01fea981b58d7b115e76164James Dong                if (isMalFormed) {
442329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Video is malformed");
4424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer->release();
4425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer = NULL;
4426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return ERROR_MALFORMED;
4427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
4428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
4429dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (nalLength == 0) {
4430dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    continue;
4431dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
4432dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
443387afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                if (dstOffset > SIZE_MAX - 4 ||
443487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                        dstOffset + 4 > SIZE_MAX - nalLength ||
443587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                        dstOffset + 4 + nalLength > mBuffer->size()) {
443687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
443787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    android_errorWriteLog(0x534e4554, "27208621");
443887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    mBuffer->release();
443987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    mBuffer = NULL;
444087afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    return ERROR_MALFORMED;
444187afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                }
4442dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4443dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4444dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4445dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4446dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 1;
4447dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
4448dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                srcOffset += nalLength;
4449dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstOffset += nalLength;
4450dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
4451dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK_EQ(srcOffset, size);
4452dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
4453dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, dstOffset);
4454dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4455dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
445620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->meta_data()->clear();
445748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        mBuffer->meta_data()->setInt64(
44584678a6dc5f09008481524949a9667af5a6190374Andreas Huber                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4459170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        mBuffer->meta_data()->setInt64(
4460170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (targetSampleTimeUs >= 0) {
4463abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            mBuffer->meta_data()->setInt64(
4464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    kKeyTargetTime, targetSampleTimeUs);
4465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4466abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
44678bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (isSyncSample) {
44688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
44698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
44708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
447120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        ++mCurrentSampleIndex;
447220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
447320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *out = mBuffer;
447420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
447520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
447620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
447720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
447820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
447920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
448005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead(
448105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MediaBuffer **out, const ReadOptions *options) {
448205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
448305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("MPEG4Source::fragmentedRead");
448405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
448505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    CHECK(mStarted);
448605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
448705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *out = NULL;
448805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
448905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t targetSampleTimeUs = -1;
449005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
449105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t seekTimeUs;
449205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ReadOptions::SeekMode mode;
449305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
449405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
449505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int numSidxEntries = mSegments.size();
449605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (numSidxEntries != 0) {
449705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            int64_t totalTime = 0;
449805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            off64_t totalOffset = mFirstMoofOffset;
449905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            for (int i = 0; i < numSidxEntries; i++) {
450005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                const SidxEntry *se = &mSegments[i];
450105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (totalTime + se->mDurationUs > seekTimeUs) {
450205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    // The requested time is somewhere in this segment
45033f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) ||
450405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
450505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
450605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        // requested next sync, or closest sync and it was closer to the end of
450705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        // this segment
450805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        totalTime += se->mDurationUs;
450905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        totalOffset += se->mSize;
451005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    }
451105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    break;
451205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
451305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                totalTime += se->mDurationUs;
451405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                totalOffset += se->mSize;
451505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
4516ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentMoofOffset = totalOffset;
4517ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSamples.clear();
4518ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSampleIndex = 0;
4519ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            parseChunk(&totalOffset);
4520ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentTime = totalTime * mTimescale / 1000000ll;
4521ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen        } else {
4522ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            // without sidx boxes, we can only seek to 0
4523ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentMoofOffset = mFirstMoofOffset;
4524ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSamples.clear();
4525ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSampleIndex = 0;
4526ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            off64_t tmp = mCurrentMoofOffset;
4527ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            parseChunk(&tmp);
4528ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentTime = 0;
452905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
453005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
453105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mBuffer != NULL) {
453205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
453305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
453405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
453505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
453605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // fall through
453705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
453805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
453905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t offset = 0;
4540442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber    size_t size = 0;
454105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t cts = 0;
454205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    bool isSyncSample = false;
454305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    bool newBuffer = false;
454405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mBuffer == NULL) {
454505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        newBuffer = true;
454605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
454705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mCurrentSampleIndex >= mCurrentSamples.size()) {
45483f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            // move to next fragment if there is one
45493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            if (mNextMoofOffset <= mCurrentMoofOffset) {
45503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                return ERROR_END_OF_STREAM;
45513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            }
4552ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            off64_t nextMoof = mNextMoofOffset;
455305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentMoofOffset = nextMoof;
455405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentSamples.clear();
455505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentSampleIndex = 0;
455605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            parseChunk(&nextMoof);
4557ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4558ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen                return ERROR_END_OF_STREAM;
4559ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            }
456005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
456105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
456205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
456305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset = smpl->offset;
456405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size = smpl->size;
4565c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        cts = mCurrentTime + smpl->compositionOffset;
456605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mCurrentTime += smpl->duration;
456705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        isSyncSample = (mCurrentSampleIndex == 0); // XXX
456805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
456905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        status_t err = mGroup->acquire_buffer(&mBuffer);
457005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
457105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (err != OK) {
457205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer == NULL);
457305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGV("acquire_buffer returned %d", err);
457405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return err;
457505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
4576c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        if (size > mBuffer->size()) {
4577c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4578c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            return ERROR_BUFFER_TOO_SMALL;
4579c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        }
458005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
458105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
458248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
458348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    const sp<MetaData> bufmeta = mBuffer->meta_data();
458448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    bufmeta->clear();
458548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (smpl->encryptedsizes.size()) {
458648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // store clear/encrypted lengths in metadata
458748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyPlainSizes, 0,
458848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
458948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyEncryptedSizes, 0,
459048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
459148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
459248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
459348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
459448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
459548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
459648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
45973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) {
459805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (newBuffer) {
4599da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (!isInRange((size_t)0u, mBuffer->size(), size)) {
4600da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer->release();
4601da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer = NULL;
4602da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
4603da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
4604da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                return ERROR_MALFORMED;
4605da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
4606da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
460705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ssize_t num_bytes_read =
460805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
460905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
461005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (num_bytes_read < (ssize_t)size) {
461105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->release();
461205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer = NULL;
461305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4614da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                ALOGE("i/o error");
461505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_IO;
461605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
461705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
461805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
461905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, size);
462005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt64(
462105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4622170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            mBuffer->meta_data()->setInt64(
4623170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
462405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
462505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (targetSampleTimeUs >= 0) {
462605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->meta_data()->setInt64(
462705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        kKeyTargetTime, targetSampleTimeUs);
462805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
462905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
463005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (isSyncSample) {
463105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
463205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
463305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
463405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ++mCurrentSampleIndex;
463505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
463605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
46373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!mIsAVC && !mIsHEVC) {
463805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *out = mBuffer;
463905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
464005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
464105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return OK;
464205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
464305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
464405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // Each NAL unit is split up into its constituent fragments and
464505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // each one of them returned in its own buffer.
464605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
464705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(mBuffer->range_length() >= mNALLengthSize);
464805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
464905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const uint8_t *src =
465005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
465105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
465205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size_t nal_size = parseNALSize(src);
46535d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mNALLengthSize > SIZE_MAX - nal_size) {
46545d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen            ALOGE("b/24441553, b/24445122");
46555d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        }
46565d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen
46575d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
465805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGE("incomplete NAL unit.");
465905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
466005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
466105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
466205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
466305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
466405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
466505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
466605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MediaBuffer *clone = mBuffer->clone();
466705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(clone != NULL);
466805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
466905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
467005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(mBuffer != NULL);
467105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer->set_range(
467205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->range_offset() + mNALLengthSize + nal_size,
467305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->range_length() - mNALLengthSize - nal_size);
467405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
467505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mBuffer->range_length() == 0) {
467605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
467705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
467805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
467905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
468005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        *out = clone;
468105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
468205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
468305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
468405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ALOGV("whole NAL");
468505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // Whole NAL units are returned but each fragment is prefixed by
468605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // the start code (0x00 00 00 01).
468705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ssize_t num_bytes_read = 0;
468805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int32_t drm = 0;
468905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
4690da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        void *data = NULL;
4691da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        bool isMalFormed = false;
469205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (usesDRM) {
4693da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
4694da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = true;
4695da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            } else {
4696da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                data = mBuffer->data();
4697da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
469805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        } else {
4699da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            int32_t max_size;
4700da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mFormat == NULL
4701da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    || !mFormat->findInt32(kKeyMaxInputSize, &max_size)
4702da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    || !isInRange((size_t)0u, (size_t)max_size, size)) {
4703da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = true;
4704da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            } else {
4705da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                data = mSrcBuffer;
4706da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
470705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
470805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4709da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        if (isMalFormed || data == NULL) {
4710da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            ALOGE("isMalFormed size %zu", size);
4711da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mBuffer != NULL) {
4712da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer->release();
4713da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer = NULL;
4714da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
4715da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            return ERROR_MALFORMED;
4716da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        }
4717da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        num_bytes_read = mDataSource->readAt(offset, data, size);
4718da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
471905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (num_bytes_read < (ssize_t)size) {
472005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
472105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
472205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4723da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            ALOGE("i/o error");
472405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_IO;
472505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
472605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
472705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (usesDRM) {
472805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
472905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, size);
473005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
473105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        } else {
473205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            uint8_t *dstData = (uint8_t *)mBuffer->data();
473305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            size_t srcOffset = 0;
473405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            size_t dstOffset = 0;
473505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
473605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            while (srcOffset < size) {
4737da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
473805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                size_t nalLength = 0;
473905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (!isMalFormed) {
474005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
474105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    srcOffset += mNALLengthSize;
4742da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
4743da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
4744da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
474505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
474605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
474705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (isMalFormed) {
4748da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    ALOGE("Video is malformed; nalLength %zu", nalLength);
474905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    mBuffer->release();
475005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    mBuffer = NULL;
475105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return ERROR_MALFORMED;
475205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
475305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
475405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (nalLength == 0) {
475505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    continue;
475605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
475705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
47585403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                if (dstOffset > SIZE_MAX - 4 ||
47595403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                        dstOffset + 4 > SIZE_MAX - nalLength ||
47605403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                        dstOffset + 4 + nalLength > mBuffer->size()) {
47615403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
47625403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    android_errorWriteLog(0x534e4554, "26365349");
47635403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    mBuffer->release();
47645403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    mBuffer = NULL;
47655403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    return ERROR_MALFORMED;
47665403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                }
476705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
476805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
476905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
477005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
477105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 1;
477205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
477305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                srcOffset += nalLength;
477405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstOffset += nalLength;
477505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
477605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK_EQ(srcOffset, size);
477705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
477805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, dstOffset);
477905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
478005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
478105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer->meta_data()->setInt64(
478205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4783170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        mBuffer->meta_data()->setInt64(
4784170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
478505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
478605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (targetSampleTimeUs >= 0) {
478705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt64(
478805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    kKeyTargetTime, targetSampleTimeUs);
478905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
479005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
479105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (isSyncSample) {
479205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
479305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
479405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
479505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ++mCurrentSampleIndex;
479605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
479705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        *out = mBuffer;
479805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer = NULL;
479905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
480005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
480105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
480205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
480305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4804bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
4805bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        const char *mimePrefix) {
4806bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    for (Track *track = mFirstTrack; track != NULL; track = track->next) {
4807bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        const char *mime;
4808bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        if (track->meta != NULL
4809bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                && track->meta->findCString(kKeyMIMEType, &mime)
4810bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
4811bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber            return track;
4812bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        }
4813bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    }
4814bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber
4815bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    return NULL;
4816bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber}
4817bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber
48181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4(
4819693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
482020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
482120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
482234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    ssize_t n = source->readAt(4, header, sizeof(header));
482320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (n < (ssize_t)sizeof(header)) {
482420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
482520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
482620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
482720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
4828b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
4829b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
48300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
4831ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
4832983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
483318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
48345a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        *confidence = 0.4;
483520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
483620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return true;
483720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
483820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
483920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return false;
484020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
484120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) {
48431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    static const uint32_t kCompatibleBrands[] = {
48441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', 'm'),
48451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', '2'),
48461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('a', 'v', 'c', '1'),
48473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        FOURCC('h', 'v', 'c', '1'),
48483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        FOURCC('h', 'e', 'v', '1'),
48491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('3', 'g', 'p', '4'),
48501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '1'),
48511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '2'),
48524cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong
48534cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        // Won't promise that the following file types can be played.
48544cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        // Just give these file types a chance.
48554cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
48564cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
485758fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber
485858fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber        FOURCC('3', 'g', '2', 'a'),  // 3GPP2
485958fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber        FOURCC('3', 'g', '2', 'b'),
48601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    };
48611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
48621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    for (size_t i = 0;
48631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
48641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         ++i) {
48651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        if (kCompatibleBrands[i] == fourcc) {
48661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            return true;
48671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
48681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
48691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
48701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
48711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
48721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
48731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable
48741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present.
4875a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends
4876a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of
4877a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata.
48781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4(
4879a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
4880a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        sp<AMessage> *meta) {
4881a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    // We scan up to 128 bytes to identify this file as an MP4.
4882a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    static const off64_t kMaxScanOffset = 128ll;
48831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
4884a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    off64_t offset = 0ll;
4885a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    bool foundGoodFileType = false;
4886a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    off64_t moovAtomEndOffset = -1ll;
4887a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    bool done = false;
48881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
4889a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    while (!done && offset < kMaxScanOffset) {
4890a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint32_t hdr[2];
4891a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        if (source->readAt(offset, hdr, 8) < 8) {
4892a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            return false;
4893a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        }
4894a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4895a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint64_t chunkSize = ntohl(hdr[0]);
4896a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint32_t chunkType = ntohl(hdr[1]);
4897a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        off64_t chunkDataOffset = offset + 8;
4898a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4899a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        if (chunkSize == 1) {
4900a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
49011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                return false;
49021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
49031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
4904a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            chunkSize = ntoh64(chunkSize);
4905a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            chunkDataOffset += 8;
4906a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4907a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            if (chunkSize < 16) {
4908a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                // The smallest valid chunk is 16 bytes long in this case.
4909a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                return false;
4910a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            }
4911452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen
4912a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        } else if (chunkSize < 8) {
4913a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            // The smallest valid chunk is 8 bytes long.
4914a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            return false;
4915a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        }
4916a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4917452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        // (data_offset - offset) is either 8 or 16
4918452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset);
4919452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        if (chunkDataSize < 0) {
4920452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen            ALOGE("b/23540914");
4921452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen            return ERROR_MALFORMED;
4922452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        }
4923a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
492405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        char chunkstring[5];
492505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MakeFourCCString(chunkType, chunkstring);
4926ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
4927a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        switch (chunkType) {
4928a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            case FOURCC('f', 't', 'y', 'p'):
4929a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            {
4930a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                if (chunkDataSize < 8) {
4931a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    return false;
4932a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
4933a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4934a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
4935a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
4936a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (i == 1) {
4937a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // Skip this index, it refers to the minorVersion,
4938a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // not a brand.
4939a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        continue;
4940a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
4941a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4942a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    uint32_t brand;
4943a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (source->readAt(
4944a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
4945a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        return false;
4946a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
4947a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4948a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    brand = ntohl(brand);
4949a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4950a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (isCompatibleBrand(brand)) {
4951a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        foundGoodFileType = true;
4952a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        break;
4953a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
4954a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
4955a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4956a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                if (!foundGoodFileType) {
4957a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    return false;
4958a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
4959a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
49601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                break;
49611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
4962a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4963a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            case FOURCC('m', 'o', 'o', 'v'):
4964a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            {
4965a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                moovAtomEndOffset = offset + chunkSize;
4966a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4967a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                done = true;
4968a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                break;
4969a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            }
4970a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4971a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            default:
4972a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                break;
49731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
4974a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4975a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        offset += chunkSize;
49761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
49771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
4978a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (!foundGoodFileType) {
49791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return false;
49801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
49811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
49821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
49835a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    *confidence = 0.4f;
49841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
4985a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (moovAtomEndOffset >= 0) {
4986a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        *meta = new AMessage;
4987a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
4988a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
4989ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset);
4990a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    }
4991a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
49921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return true;
49931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
49941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
49951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4(
49965a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
4997a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        sp<AMessage> *meta) {
4998a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
49991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
50001b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
50011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
50021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (LegacySniffMPEG4(source, mimeType, confidence)) {
50035ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
50041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
50051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
50061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
50071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
50081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
50091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
501020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
5011