MPEG4Extractor.cpp revision ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381a
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"
474dbff11975e737482537e1636051690188f3fbc4Praveen Chavan#include "include/avc_utils.h"
48fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
49937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#ifndef UINT32_MAX
50937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#define UINT32_MAX       (4294967295U)
51937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#endif
52937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
550dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnarenum {
560dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar    // max track header chunk to return
570dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar    kMaxTrackHeaderSize = 32,
582fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen
592fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen    // maximum size of an atom. Some atoms can be bigger according to the spec,
602fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen    // but we only allow up to this size.
612fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen    kMaxAtomSize = 64 * 1024 * 1024,
620dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar};
630dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource {
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic:
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // Caller retains ownership of both "dataSource" and "sampleTable".
67942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    MPEG4Source(const sp<MPEG4Extractor> &owner,
68942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen                const sp<MetaData> &format,
69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                const sp<DataSource> &dataSource,
7048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                int32_t timeScale,
7105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                const sp<SampleTable> &sampleTable,
7205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                Vector<SidxEntry> &sidx,
73c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                const Trex *trex,
7405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                off64_t firstMoofOffset);
75ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    virtual status_t init();
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t start(MetaData *params = NULL);
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t stop();
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual sp<MetaData> getFormat();
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
83cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    virtual bool supportNonblockingRead() { return true; }
8405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL);
8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
86693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
87693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~MPEG4Source();
88693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate:
907b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex mLock;
917b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
92942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    // keep the MPEG4Extractor around, since we're referencing its data
93942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    sp<MPEG4Extractor> mOwner;
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> mFormat;
95693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<DataSource> mDataSource;
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t mTimescale;
97693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<SampleTable> mSampleTable;
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t mCurrentSampleIndex;
9905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t mCurrentFragmentIndex;
10005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Vector<SidxEntry> &mSegments;
101c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    const Trex *mTrex;
10205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t mFirstMoofOffset;
10305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t mCurrentMoofOffset;
10405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t mNextMoofOffset;
10505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t mCurrentTime;
10605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int32_t mLastParsedTrackId;
10705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int32_t mTrackId;
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int32_t mCryptoMode;    // passed in from extractor
110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int32_t mDefaultIVSize; // passed in from extractor
111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t mCryptoKey[16]; // passed in from extractor
112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentAuxInfoType;
113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentAuxInfoTypeParameter;
11448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    int32_t mCurrentDefaultSampleInfoSize;
115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoCount;
116ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoAllocSize;
117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t* mCurrentSampleInfoSizes;
118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoOffsetCount;
119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t mCurrentSampleInfoOffsetsAllocSize;
120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint64_t* mCurrentSampleInfoOffsets;
121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool mIsAVC;
1233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    bool mIsHEVC;
1246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    size_t mNALLengthSize;
1256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool mStarted;
12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBufferGroup *mGroup;
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *mBuffer;
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
132dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool mWantsNALFragments;
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1340024245e134467d120b40099da16c467dc365e76Andreas Huber    uint8_t *mSrcBuffer;
1350024245e134467d120b40099da16c467dc365e76Andreas Huber
1366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    size_t parseNALSize(const uint8_t *data) const;
13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    status_t parseChunk(off64_t *offset);
13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    status_t parseTrackFragmentRun(off64_t offset, off64_t size);
140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    struct TrackFragmentHeaderInfo {
14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        enum Flags {
14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kBaseDataOffsetPresent         = 0x01,
14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kSampleDescriptionIndexPresent = 0x02,
14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDefaultSampleDurationPresent  = 0x08,
14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDefaultSampleSizePresent      = 0x10,
14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDefaultSampleFlagsPresent     = 0x20,
15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            kDurationIsEmpty               = 0x10000,
15105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        };
15205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
15305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mTrackID;
15405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mFlags;
15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint64_t mBaseDataOffset;
15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mSampleDescriptionIndex;
15705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mDefaultSampleDuration;
15805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mDefaultSampleSize;
15905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t mDefaultSampleFlags;
16005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
16105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint64_t mDataOffset;
16205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
16305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
16405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
16505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    struct Sample {
16605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t offset;
16705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size_t size;
16805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t duration;
169c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        int32_t compositionOffset;
170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        uint8_t iv[16];
171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Vector<size_t> clearsizes;
172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Vector<size_t> encryptedsizes;
17305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
17405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Vector<Sample> mCurrentSamples;
1756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MPEG4Source(const MPEG4Source &);
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MPEG4Source &operator=(const MPEG4Source &);
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber};
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests
18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding
18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource.
18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track,
18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e.
18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track.
18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource {
188090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit MPEG4DataSource(const sp<DataSource> &source);
18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual status_t initCheck() const;
191c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
192c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    virtual status_t getSize(off64_t *size);
19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual uint32_t flags();
19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
195c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    status_t setCachedRange(off64_t offset, size_t size);
19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected:
19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual ~MPEG4DataSource();
19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate:
20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex mLock;
20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    sp<DataSource> mSource;
204c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCachedOffset;
20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    size_t mCachedSize;
20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    uint8_t *mCache;
20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    void clearCache();
20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource(const MPEG4DataSource &);
21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource &operator=(const MPEG4DataSource &);
21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber};
21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    : mSource(source),
21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCachedOffset(0),
21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCachedSize(0),
21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCache(NULL) {
21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() {
22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    clearCache();
22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() {
22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (mCache) {
22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        free(mCache);
22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        mCache = NULL;
22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedOffset = 0;
23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedSize = 0;
23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const {
23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->initCheck();
23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
239c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex::Autolock autoLock(mLock);
24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
242bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar    if (isInRange(mCachedOffset, mCachedSize, offset, size)) {
24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        memcpy(data, &mCache[offset - mCachedOffset], size);
24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return size;
24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->readAt(offset, data, size);
24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
250c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) {
25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->getSize(size);
25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() {
25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->flags();
25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
258c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) {
25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex::Autolock autoLock(mLock);
26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    clearCache();
26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCache = (uint8_t *)malloc(size);
26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (mCache == NULL) {
26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return -ENOMEM;
26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
26850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
26950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedOffset = offset;
27050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedSize = size;
27150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
27250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
27350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
27450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (err < (ssize_t)size) {
27550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        clearCache();
27650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
27750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return ERROR_IO;
27850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
27950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
28050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return OK;
28150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
28250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
28350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber////////////////////////////////////////////////////////////////////////////////
28450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
285b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false;
286b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) {
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const uint8_t *data = (const uint8_t *)_data;
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t offset = 0;
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (offset < size) {
291377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT        printf("0x%04zx  ", offset);
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t n = size - offset;
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (n > 16) {
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            n = 16;
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (size_t i = 0; i < 16; ++i) {
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (i == 8) {
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(" ");
30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (offset + i < size) {
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("%02x ", data[offset + i]);
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("   ");
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf(" ");
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (size_t i = 0; i < n; ++i) {
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (isprint(data[offset + i])) {
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("%c", data[offset + i]);
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(".");
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("\n");
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        offset += 16;
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) {
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    switch (fourcc) {
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
32918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AAC;
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
33218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
334371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
33518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
336371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
33818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_MPEG4;
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
341e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('h', '2', '6', '3'):
342e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('H', '2', '6', '3'):
34318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_H263;
34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
34618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_AVC;
34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', '1'):
3493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'e', 'v', '1'):
3503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            return MEDIA_MIMETYPE_VIDEO_HEVC;
35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
352dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            CHECK(!"should not be here.");
35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) {
35848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) {
35948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // AMR NB audio is always mono, 8kHz
36048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *channels = 1;
36148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *rate = 8000;
36248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return true;
36348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) {
36448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // AMR WB audio is always mono, 16kHz
36548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *channels = 1;
36648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        *rate = 16000;
36748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return true;
36848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
36948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    return false;
37048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen}
37148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
372693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
373c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    : mMoofOffset(0),
374928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang      mMoofFound(false),
375928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang      mMdatFound(false),
37605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mDataSource(source),
377bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber      mInitCheck(NO_INIT),
378fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen      mHeaderTimescale(0),
379bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia      mIsQT(false),
38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mFirstTrack(NULL),
38172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber      mLastTrack(NULL),
382dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFileMetaData(new MetaData),
383dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFirstSINF(NULL),
384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mIsDrm(false) {
38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() {
38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (track) {
39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        Track *next = track->next;
39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete track;
39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = next;
39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mFirstTrack = mLastTrack = NULL;
396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    SINF *sinf = mFirstSINF;
398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (sinf) {
399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        SINF *next = sinf->next;
4008da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        delete[] sinf->IPMPData;
401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        delete sinf;
402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf = next;
403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mFirstSINF = NULL;
405ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
406ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mPssh.size(); i++) {
407ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        delete [] mPssh[i].data;
408ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
41105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const {
41205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return CAN_PAUSE |
41305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ((mMoofOffset == 0 || mSidxEntries.size() != 0) ?
41405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
41505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
41605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4177be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() {
4187be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    status_t err;
4197be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if ((err = readMetaData()) != OK) {
42072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return new MetaData;
4217be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
4227be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
42372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return mFileMetaData;
4247be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
4257be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() {
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
429ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        ALOGV("MPEG4Extractor::countTracks: no tracks");
430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return 0;
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (track) {
436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++n;
43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
440a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("MPEG4Extractor::countTracks: %zu tracks", n);
441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(
4457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t index, uint32_t flags) {
44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return NULL;
44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
461371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
462371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
463371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
464371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
4657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if ((flags & kIncludeExtensiveMetaData)
4667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            && !track->includes_expensive_metadata) {
4677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        track->includes_expensive_metadata = true;
4687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
4697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        const char *mime;
4707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
4717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (!strncasecmp("video/", mime, 6)) {
47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (mMoofOffset > 0) {
47305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                int64_t duration;
47405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (track->meta->findInt64(kKeyDuration, &duration)) {
47505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    // nothing fancy, just pick a frame near 1/4th of the duration
47605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    track->meta->setInt64(
47705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            kKeyThumbnailTime, duration / 4);
47805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
47905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            } else {
48005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t sampleIndex;
48105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t sampleTime;
4820d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                if (track->timescale != 0 &&
4830d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                        track->sampleTable->findThumbnailSample(&sampleIndex) == OK
48405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        && track->sampleTable->getMetaDataForSample(
48505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            sampleIndex, NULL /* offset */, NULL /* size */,
48605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            &sampleTime) == OK) {
48705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    track->meta->setInt64(
48805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            kKeyThumbnailTime,
48905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            ((int64_t)sampleTime * 1000000) / track->timescale);
49005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
4917e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            }
4920dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar
4930dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar            // MPEG2 tracks do not provide CSD, so read the stream header
4940dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar            if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
4950dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                off64_t offset;
4960dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                size_t size;
4970dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                if (track->sampleTable->getMetaDataForSample(
4980dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                            0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
4990dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    if (size > kMaxTrackHeaderSize) {
5000dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                        size = kMaxTrackHeaderSize;
5010dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    }
5020dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    uint8_t header[kMaxTrackHeaderSize];
5030dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
5040dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                        track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
5050dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                    }
5060dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar                }
5070dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar            }
5087e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
5097e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
5107e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return track->meta;
51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) {
51548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[0] = x >> 24;
51648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[1] = (x >> 16) & 0xff;
51748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[2] = (x >> 8) & 0xff;
51848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[3] = x & 0xff;
51948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    s[4] = '\0';
52048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen}
52148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() {
523bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    if (mInitCheck != NO_INIT) {
524bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        return mInitCheck;
52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
527c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset = 0;
52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
529928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang    bool sawMoovOrSidx = false;
530928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
531928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang    while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) {
532a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        off64_t orig_offset = offset;
53305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        err = parseChunk(&offset, 0);
534a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen
5354ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar        if (err != OK && err != UNKNOWN_ERROR) {
5364ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar            break;
5374ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar        } else if (offset <= orig_offset) {
538a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // only continue parsing if the offset was advanced,
539a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // otherwise we might end up in an infinite loop
540ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset);
541a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            err = ERROR_MALFORMED;
542a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            break;
543928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang        } else if (err == UNKNOWN_ERROR) {
544928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            sawMoovOrSidx = true;
54505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
5477be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
548bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    if (mInitCheck == OK) {
54955fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia        if (findTrackByMimePrefix("video/") != NULL) {
550bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber            mFileMetaData->setCString(
551bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
55255fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia        } else if (findTrackByMimePrefix("audio/") != NULL) {
55372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
55455fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia        } else {
55555fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia            mFileMetaData->setCString(kKeyMIMEType, "application/octet-stream");
55672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
557bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    } else {
558bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        mInitCheck = err;
55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
561bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    CHECK_NE(err, (status_t)NO_INIT);
562ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
563ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // copy pssh data into file metadata
564c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen    uint64_t psshsize = 0;
565ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mPssh.size(); i++) {
566ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        psshsize += 20 + mPssh[i].datalen;
567ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
568c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen    if (psshsize > 0 && psshsize <= UINT32_MAX) {
569ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        char *buf = (char*)malloc(psshsize);
5706a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen        if (!buf) {
5716a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            ALOGE("b/28471206");
5726a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            return NO_MEMORY;
5736a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen        }
574ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        char *ptr = buf;
575ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        for (size_t i = 0; i < mPssh.size(); i++) {
576ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
577ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
578ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ptr += (20 + mPssh[i].datalen);
579ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
580ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize);
581ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        free(buf);
582ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
583bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    return mInitCheck;
58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mFirstSINF == NULL) {
588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return NULL;
589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    SINF *sinf = mFirstSINF;
592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (sinf && (trackID != sinf->trackID)) {
593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf = sinf->next;
594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (sinf == NULL) {
597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return NULL;
598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *len = sinf->len;
601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return sinf->IPMPData;
602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset,
60640d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh        const sp<DataSource> &DataSource, uint8_t *numOfBytes) {
607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint32_t size = 0;
608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t data;
609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    bool moreData = true;
610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *numOfBytes = 0;
611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (moreData) {
613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (DataSource->readAt(offset, &data, 1) < 1) {
614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return -1;
615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        offset ++;
617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        moreData = (data >= 128) ? true : false;
618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size = (size << 7) | (data & 0x7f); // Take last 7 bits
619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        (*numOfBytes) ++;
620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return size;
623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
62584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF(
62684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t * /* offset */, off64_t data_offset) {
627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t updateIdTag;
628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset ++;
632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t numOfBytes;
638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size < 0) {
640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset += numOfBytes;
643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while(size >= 11 ) {
645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t descriptorTag;
646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset ++;
650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t buffer[8];
656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        //ObjectDescriptorID and ObjectDescriptor url flag
657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset += 2;
661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if ((buffer[1] >> 5) & 0x0001) { //url flag is set
663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset += 8;
670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        SINF *sinf = new SINF;
677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->trackID = U16_AT(&buffer[3]);
678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->IPMPDescriptorID = buffer[7];
679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->next = mFirstSINF;
680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mFirstSINF = sinf;
681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size -= (8 + 2 + 1);
683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size != 0) {
686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset ++;
693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size = readSize(data_offset, mDataSource, &numOfBytes);
699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size < 0) {
700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset += numOfBytes;
703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (size > 0) {
705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t tag;
706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t dataLen;
707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset ++;
711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t id;
714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dataLen = readSize(data_offset, mDataSource, &numOfBytes);
715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (dataLen < 0) {
716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            } else if (dataLen < 4) {
718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset += numOfBytes;
721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (mDataSource->readAt(data_offset, &id, 1) < 1) {
723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
725dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset ++;
726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
727dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            SINF *sinf = mFirstSINF;
728dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (sinf && (sinf->IPMPDescriptorID != id)) {
729dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                sinf = sinf->next;
730dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
731dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (sinf == NULL) {
732dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
733dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
734dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            sinf->len = dataLen - 3;
7358da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            sinf->IPMPData = new (std::nothrow) char[sinf->len];
7368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (sinf->IPMPData == NULL) {
7378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
7388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
739f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara            data_offset += 2;
740dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
741f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara            if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) {
742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset += sinf->len;
745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size -= (dataLen + numOfBytes + 1);
747dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
748dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
749dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
750dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size != 0) {
751dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
752dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
753dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
754dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return UNKNOWN_ERROR;  // Return a dummy error.
755dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
756dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder {
75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        : mPath(path) {
76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        mPath->push(chunkType);
76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
76372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    ~PathAdder() {
76472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        mPath->pop();
76572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
76672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
76772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate:
76872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    Vector<uint32_t> *mPath;
76972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
77072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder(const PathAdder &);
77172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder &operator=(const PathAdder &);
77272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber};
77372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
77472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) {
77572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return path.size() >= 5
77672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[0] == FOURCC('m', 'o', 'o', 'v')
77772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[1] == FOURCC('u', 'd', 't', 'a')
77872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[2] == FOURCC('m', 'e', 't', 'a')
77972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[3] == FOURCC('i', 'l', 's', 't');
78072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
78172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
7828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) {
7838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return path.size() >= 2
7848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            && path[0] == FOURCC('m', 'o', 'o', 'v')
7858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            && path[1] == FOURCC('m', 'e', 't', 'a')
7868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            && (depth == 2
7878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || (depth == 3
788ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                    && (path[2] == FOURCC('h', 'd', 'l', 'r')
789ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                    ||  path[2] == FOURCC('i', 'l', 's', 't')
7908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    ||  path[2] == FOURCC('k', 'e', 'y', 's'))));
7918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
7928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
79372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string.
7943724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissenstatic bool convertTimeToDate(int64_t time_1904, String8 *s) {
7953724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    // delta between mpeg4 time and unix epoch time
7963724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    static const int64_t delta = (((66 * 365 + 17) * 24) * 3600);
7973724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    if (time_1904 < INT64_MIN + delta) {
7983724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen        return false;
7993724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    }
8003724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    time_t time_1970 = time_1904 - delta;
80172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
80272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    char tmp[32];
8033724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    struct tm* tm = gmtime(&time_1970);
8043724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    if (tm != NULL &&
8053724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
8063724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen        s->setTo(tmp);
8073724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen        return true;
8083724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    }
8093724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen    return false;
81072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
81172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
812c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
813ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth);
814452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen
815452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    if (*offset < 0) {
816452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        ALOGE("b/23540914");
817452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        return ERROR_MALFORMED;
818452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    }
819dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen    if (depth > 100) {
820dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen        ALOGE("b/27456299");
821dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen        return ERROR_MALFORMED;
822dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen    }
82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t hdr[2];
82434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint64_t chunk_size = ntohl(hdr[0]);
8282d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer    int32_t chunk_type = ntohl(hdr[1]);
829c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t data_offset = *offset + 8;
83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (chunk_size == 1) {
83234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_IO;
83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        chunk_size = ntoh64(chunk_size);
83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        data_offset += 8;
83771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber
83871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        if (chunk_size < 16) {
83971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber            // The smallest valid chunk is 16 bytes long in this case.
84071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber            return ERROR_MALFORMED;
84171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        }
842a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen    } else if (chunk_size == 0) {
843a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        if (depth == 0) {
844a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // atom extends to end of file
845a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            off64_t sourceSize;
846a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            if (mDataSource->getSize(&sourceSize) == OK) {
847a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                chunk_size = (sourceSize - *offset);
848a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            } else {
849a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                // XXX could we just pick a "sufficiently large" value here?
850a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                ALOGE("atom size is 0, and data source has no size");
851a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen                return ERROR_MALFORMED;
852a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            }
853a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        } else {
854a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            // not allowed for non-toplevel atoms, skip it
855a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            *offset += 4;
856a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen            return OK;
857a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen        }
85871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber    } else if (chunk_size < 8) {
85971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        // The smallest valid chunk is 8 bytes long.
860a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGE("invalid chunk size: %" PRIu64, chunk_size);
86171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        return ERROR_MALFORMED;
86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    char chunk[5];
86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MakeFourCCString(chunk_type, chunk);
866ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth);
86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
868b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    if (kUseHexDump) {
869b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        static const char kWhitespace[] = "                                        ";
870b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
871b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size);
87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
873b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        char buffer[256];
874b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t n = chunk_size;
875b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        if (n > sizeof(buffer)) {
876b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            n = sizeof(buffer);
877b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        }
878b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        if (mDataSource->readAt(*offset, buffer, n)
879b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                < (ssize_t)n) {
880b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            return ERROR_IO;
881b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        }
882ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
883b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        hexdump(buffer, n);
884b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    }
88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
88672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder autoAdder(&mPath, chunk_type);
88772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
888452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    // (data_offset - *offset) is either 8 or 16
889452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    off64_t chunk_data_size = chunk_size - (data_offset - *offset);
890452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    if (chunk_data_size < 0) {
891452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        ALOGE("b/23540914");
892452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        return ERROR_MALFORMED;
893452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen    }
8942fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen    if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) {
8952fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen        char errMsg[100];
8962fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen        sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
8972fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen        ALOGE("%s (b/28615448)", errMsg);
8982fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen        android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg));
8992fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen        return ERROR_MALFORMED;
9002fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen    }
90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
90272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (chunk_type != FOURCC('c', 'p', 'r', 't')
903515e855eae78aa495da58356486aaa666cb57fd1James Dong            && chunk_type != FOURCC('c', 'o', 'v', 'r')
90472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            && mPath.size() == 5 && underMetaDataPath(mPath)) {
905c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t stop_offset = *offset + chunk_size;
90672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        *offset = data_offset;
90772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        while (*offset < stop_offset) {
90872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            status_t err = parseChunk(offset, depth + 1);
90972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (err != OK) {
91072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return err;
91172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
91272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (*offset != stop_offset) {
915bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
916bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
91772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
91872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return OK;
91972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
92072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    switch(chunk_type) {
92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'o', 'o', 'v'):
92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'r', 'a', 'k'):
92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'i', 'a'):
92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'i', 'n', 'f'):
92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('d', 'i', 'n', 'f'):
92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'b', 'l'):
92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'v', 'e', 'x'):
92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'o', 'o', 'f'):
93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'r', 'a', 'f'):
93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'f', 'r', 'a'):
93272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('u', 'd', 't', 'a'):
93372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('i', 'l', 's', 't'):
934ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'i', 'n', 'f'):
935ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'c', 'h', 'i'):
9360a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        case FOURCC('e', 'd', 't', 's'):
937bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        case FOURCC('w', 'a', 'v', 'e'):
93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
9390d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen            if (chunk_type == FOURCC('m', 'o', 'o', 'v') && depth != 0) {
9400d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                ALOGE("moov: depth %d", depth);
9410d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                return ERROR_MALFORMED;
9420d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen            }
943928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) {
944928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang                // store the offset of the first segment
945928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang                mMoofFound = true;
946928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang                mMoofOffset = *offset;
947928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            }
948928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
94950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
950a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
95150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
952b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                if (mDataSource->flags()
953b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                        & (DataSource::kWantsPrefetching
954b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                            | DataSource::kIsCachingDataSource)) {
95550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    sp<MPEG4DataSource> cachedSource =
95650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                        new MPEG4DataSource(mDataSource);
95750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
95850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
95950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                        mDataSource = cachedSource;
96050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    }
96150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                }
9621edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber
963f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                if (mLastTrack == NULL)
964f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                    return ERROR_MALFORMED;
965f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
9661edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber                mLastTrack->sampleTable = new SampleTable(mDataSource);
96750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            }
96850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
9696f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber            bool isTrack = false;
970bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
9710d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                if (depth != 1) {
9720d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                    ALOGE("trak: depth %d", depth);
9730d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                    return ERROR_MALFORMED;
9740d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                }
9756f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                isTrack = true;
9766f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
977bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                Track *track = new Track;
978bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->next = NULL;
979bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                if (mLastTrack) {
980bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    mLastTrack->next = track;
981bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                } else {
982bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    mFirstTrack = track;
983bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                }
984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                mLastTrack = track;
985bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
986bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->meta = new MetaData;
987bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->includes_expensive_metadata = false;
9886f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                track->skipTrack = false;
989bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->timescale = 0;
990bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
991bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
992bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
993c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset;
99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
9980d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                    if (isTrack) {
9990d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                        mLastTrack->skipTrack = true;
10000d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                        break;
10010d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                    }
100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1006bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1007bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1008bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
1009bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
10106f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber            if (isTrack) {
10110386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                int32_t trackId;
10120386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                // There must be exact one track header per track.
10130386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
10140386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                    mLastTrack->skipTrack = true;
10150386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                }
10166f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                if (mLastTrack->skipTrack) {
10176f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    Track *cur = mFirstTrack;
10186f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
10196f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    if (cur == mLastTrack) {
10206f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        delete cur;
10216f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        mFirstTrack = mLastTrack = NULL;
10226f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    } else {
10236f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        while (cur && cur->next != mLastTrack) {
10246f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                            cur = cur->next;
10256f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        }
1026f303d743250d2754209980bb42017b9668cf163fCaroline Tice                        if (cur) {
1027f303d743250d2754209980bb42017b9668cf163fCaroline Tice                            cur->next = NULL;
1028f303d743250d2754209980bb42017b9668cf163fCaroline Tice                        }
10296f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        delete mLastTrack;
10306f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        mLastTrack = cur;
10316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    }
10326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
10336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    return OK;
10346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                }
10356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
1036bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                status_t err = verifyTrack(mLastTrack);
1037bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1038bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                if (err != OK) {
1039bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    return err;
1040bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                }
1041bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
1042bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                mInitCheck = OK;
104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1044dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (!mIsDrm) {
1045dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return UNKNOWN_ERROR;  // Return a dummy error.
1046dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                } else {
1047dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return OK;
1048dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        case FOURCC('e', 'l', 's', 't'):
10540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        {
10550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
10560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
10570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            // See 14496-12 8.6.6
10580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            uint8_t version;
10590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
10600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                return ERROR_IO;
10610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            }
10620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            uint32_t entry_count;
10640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) {
10650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                return ERROR_IO;
10660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            }
10670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            if (entry_count != 1) {
10690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                // we only support a single entry at the moment, for gapless playback
10700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                ALOGW("ignoring edit list with %d entries", entry_count);
1071fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen            } else if (mHeaderTimescale == 0) {
1072210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen                ALOGW("ignoring edit list because timescale is 0");
10730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            } else {
10740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                off64_t entriesoffset = data_offset + 8;
10750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                uint64_t segment_duration;
10760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                int64_t media_time;
10770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
10780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                if (version == 1) {
10790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    if (!mDataSource->getUInt64(entriesoffset, &segment_duration) ||
10800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                            !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) {
10810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                        return ERROR_IO;
10820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    }
10830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                } else if (version == 0) {
10840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    uint32_t sd;
10850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    int32_t mt;
10860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    if (!mDataSource->getUInt32(entriesoffset, &sd) ||
10870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                            !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) {
10880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                        return ERROR_IO;
10890a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    }
10900a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    segment_duration = sd;
10910a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    media_time = mt;
10920a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                } else {
10930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    return ERROR_IO;
10940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                }
10950a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
1096fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                uint64_t halfscale = mHeaderTimescale / 2;
1097fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale;
1098fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale;
10990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
11000a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                int64_t duration;
11010a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                int32_t samplerate;
11021391f933b49cfb56da9aa63f723de83b076cf888Robert Shih                if (!mLastTrack) {
11031391f933b49cfb56da9aa63f723de83b076cf888Robert Shih                    return ERROR_MALFORMED;
11041391f933b49cfb56da9aa63f723de83b076cf888Robert Shih                }
11050a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                if (mLastTrack->meta->findInt64(kKeyDuration, &duration) &&
11060a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                        mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) {
11070a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
11080a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    int64_t delay = (media_time  * samplerate + 500000) / 1000000;
11090a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
11100a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
1111608fe1d6b2ea4d88245a109afe2bfba580881a16Wei Jia                    int64_t paddingus = duration - (int64_t)(segment_duration + media_time);
1112465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                    if (paddingus < 0) {
1113465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        // track duration from media header (which is what kKeyDuration is) might
1114465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        // be slightly shorter than the segment duration, which would make the
1115465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        // padding negative. Clamp to zero.
1116465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                        paddingus = 0;
1117465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen                    }
11180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000;
11190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                    mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples);
11200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen                }
11210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            }
11220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen            break;
11230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen        }
11240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen
1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('f', 'r', 'm', 'a'):
1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        {
11270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
11280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
112948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t original_fourcc;
1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) {
1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            original_fourcc = ntohl(original_fourcc);
1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("read original format: %d", original_fourcc);
1135f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1136f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1137f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1138f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
114048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t num_channels = 0;
114148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t sample_rate = 0;
114248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
114348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
114448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
114548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            }
1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('t', 'e', 'n', 'c'):
1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        {
11510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
11520517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (chunk_size < 32) {
1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte
1158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // default IV size, 16 bytes default KeyID
1159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // (ISO 23001-7)
1160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            char buf[4];
1161ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memset(buf, 0, 4);
1162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) {
1163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf));
1166ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (defaultAlgorithmId > 1) {
1167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // only 0 (clear) and 1 (AES-128) are valid
1168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            memset(buf, 0, 4);
1172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) {
1173ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1174ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1175ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t defaultIVSize = ntohl(*((int32_t*)buf));
1176ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1177ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((defaultAlgorithmId == 0 && defaultIVSize != 0) ||
1178ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                    (defaultAlgorithmId != 0 && defaultIVSize == 0)) {
1179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // only unencrypted data must have 0 IV size
1180ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1181ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            } else if (defaultIVSize != 0 &&
1182ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                    defaultIVSize != 8 &&
1183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                    defaultIVSize != 16) {
1184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // only supported sizes are 0, 8 and 16
1185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1186ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1187ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1188ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint8_t defaultKeyId[16];
1189ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1190ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) {
1191ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1192ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1193ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1194f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1195f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1196f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1197ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId);
1198ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize);
1199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16);
1200ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1201ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1202ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
120320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'k', 'h', 'd'):
120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
12050517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
12060517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1207ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            status_t err;
1208ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
1209ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                return err;
121020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
121120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
121220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
121320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1215ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('p', 's', 's', 'h'):
1216ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        {
12170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
12180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1219ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            PsshInfo pssh;
1220ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1221ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) {
1222ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1223ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1224ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1225ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t psshdatalen = 0;
1226ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) {
1227ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1228ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1229ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            pssh.datalen = ntohl(psshdatalen);
1230ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("pssh data size: %d", pssh.datalen);
1231c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen            if (chunk_size < 20 || pssh.datalen > chunk_size - 20) {
1232ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // pssh data length exceeds size of containing box
1233ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_MALFORMED;
1234ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1235ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
12368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            pssh.data = new (std::nothrow) uint8_t[pssh.datalen];
12378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (pssh.data == NULL) {
12388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
12398da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
1240ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("allocated pssh @ %p", pssh.data);
1241ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ssize_t requested = (ssize_t) pssh.datalen;
1242ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
1243ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1244ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1245ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mPssh.push_back(pssh);
1246ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1247ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1248ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1249ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
125020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'h', 'd'):
125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
12520517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
12530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1254202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih            if (chunk_data_size < 4 || mLastTrack == NULL) {
125520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t version;
125934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, &version, sizeof(version))
126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(version)) {
126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1265c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t timescale_offset;
126620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 16;
126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else if (version == 0) {
127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 8;
127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
127320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t timescale;
127634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        timescale_offset, &timescale, sizeof(timescale))
127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(timescale)) {
127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
128120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12822e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang            if (!timescale) {
12832e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang                ALOGE("timescale should not be ZERO.");
12842e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang                return ERROR_MALFORMED;
12852e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang            }
12862e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang
128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->timescale = ntohl(timescale);
128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1289c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            // 14496-12 says all ones means indeterminate, but some files seem to use
1290c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            // 0 instead. We treat both the same.
129105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            int64_t duration = 0;
129220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
129334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration, sizeof(duration))
129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration)) {
129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
1298c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration != -1) {
1299c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = ntoh64(duration);
1300c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
130120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
130205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t duration32;
130334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration32, sizeof(duration32))
130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration32)) {
130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
130805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (duration32 != 0xffffffff) {
130905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    duration = ntohl(duration32);
131005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
131120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1312e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake            if (duration != 0 && mLastTrack->timescale != 0) {
1313c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mLastTrack->meta->setInt64(
1314c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                        kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
1315c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
131620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            uint8_t lang[2];
13187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            off64_t lang_offset;
13197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (version == 1) {
13207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                lang_offset = timescale_offset + 4 + 8;
13217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else if (version == 0) {
13227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                lang_offset = timescale_offset + 4 + 4;
13237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else {
13247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return ERROR_IO;
13257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
13287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                    < (ssize_t)sizeof(lang)) {
13297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return ERROR_IO;
13307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // To get the ISO-639-2/T three character language code
13337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // 1 bit pad followed by 3 5-bits characters. Each character
13347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // is packed as the difference between its ASCII value and 0x60.
13357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            char lang_code[4];
13367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
13377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
13387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[2] = (lang[1] & 0x1f) + 0x60;
13397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[3] = '\0';
13407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            mLastTrack->meta->setCString(
13427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                    kKeyMediaLanguage, lang_code);
13437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
134420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'd'):
134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8];
1350c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            if (chunk_data_size < (off64_t)sizeof(buffer)) {
1351bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1352bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
1353bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
135434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, 8) < 8) {
135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t entry_count = U32_AT(&buffer[4]);
136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (entry_count > 1) {
13673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // For 3GPP timed text, there could be multiple tx3g boxes contain
13683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // multiple text display formats. These formats will be used to
13693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // display the timed text.
1370ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // For encrypted files, there may also be more than one entry.
13713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                const char *mime;
1372f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1373f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                if (mLastTrack == NULL)
1374f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                    return ERROR_MALFORMED;
1375f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
13763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1377ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
1378ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                        strcasecmp(mime, "application/octet-stream")) {
13793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    // For now we only support a single type of media per track.
13803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    mLastTrack->skipTrack = true;
13813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    *offset += chunk_size;
13823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    break;
13833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                }
138420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1385c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
138620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + 8;
138720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            for (uint32_t i = 0; i < entry_count; ++i) {
138820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
139020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1393bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1394bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1395bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1396bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
140148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        case FOURCC('e', 'n', 'c', 'a'):
140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
1403371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1405bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')
1406bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) {
1407bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                // Ignore mp4a embedded in QT wave atom
1408bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                *offset += chunk_size;
1409bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                break;
1410bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
1411bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
141220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8 + 20];
141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
141420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic AudioSampleEntry size.
141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
141620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
141834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
141920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
142120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1423b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
1424bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            uint16_t version = U16_AT(&buffer[8]);
142548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t num_channels = U16_AT(&buffer[16]);
142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
142781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint16_t sample_size = U16_AT(&buffer[18]);
142881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
142981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
1430f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1431f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1432f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1433bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            off64_t stop_offset = *offset + chunk_size;
1434bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            *offset = data_offset + sizeof(buffer);
1435bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
1436bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')) {
1437bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (version == 1) {
1438bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    if (mDataSource->readAt(*offset, buffer, 16) < 16) {
1439bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                        return ERROR_IO;
1440bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    }
1441bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
1442bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#if 0
1443bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(buffer);  // samples per packet
1444bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&buffer[4]);  // bytes per packet
1445bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&buffer[8]);  // bytes per frame
1446bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&buffer[12]);  // bytes per sample
1447bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#endif
1448bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    *offset += 16;
1449bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                } else if (version == 2) {
1450bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    uint8_t v2buffer[36];
1451bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    if (mDataSource->readAt(*offset, v2buffer, 36) < 36) {
1452bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                        return ERROR_IO;
1453bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    }
1454bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
1455bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#if 0
1456bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(v2buffer);  // size of struct only
1457bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    sample_rate = (uint32_t)U64_AT(&v2buffer[4]);  // audio sample rate
1458bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    num_channels = U32_AT(&v2buffer[12]);  // num audio channels
1459bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[16]);  // always 0x7f000000
1460bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    sample_size = (uint16_t)U32_AT(&v2buffer[20]);  // const bits per channel
1461bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[24]);  // format specifc flags
1462bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[28]);  // const bytes per audio packet
1463bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[32]);  // const LPCM frames per audio packet
1464bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#endif
1465bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    *offset += 36;
1466bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
1467bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
1468bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
146948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
147048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                // if the chunk type is enca, we'll get the type from the sinf/frma box later
147148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
147248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
147320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
147448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
147581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                   chunk, num_channels, sample_size, sample_rate);
147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
148120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
148220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
148320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
148420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1485bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1486bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1487bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1488bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
148920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
149020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
149120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
149220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
1493ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('e', 'n', 'c', 'v'):
149420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
1495e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('H', '2', '6', '3'):
1496e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('h', '2', '6', '3'):
149720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
14983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', '1'):
14993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'e', 'v', '1'):
150020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
150120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[78];
150220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic VideoSampleEntry size.
150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
150734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
150820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
150920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
151020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
151120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1512b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
151320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t width = U16_AT(&buffer[6 + 18]);
151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t height = U16_AT(&buffer[6 + 20]);
151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1516ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // The video sample is not standard-compliant if it has invalid dimension.
1517a6256238d9015c42129fe43791968768fe501efaJames Dong            // Use some default width and height value, and
1518a6256238d9015c42129fe43791968768fe501efaJames Dong            // let the decoder figure out the actual width and height (and thus
1519a6256238d9015c42129fe43791968768fe501efaJames Dong            // be prepared for INFO_FOMRAT_CHANGED event).
1520a6256238d9015c42129fe43791968768fe501efaJames Dong            if (width == 0)  width  = 352;
1521a6256238d9015c42129fe43791968768fe501efaJames Dong            if (height == 0) height = 288;
1522a6256238d9015c42129fe43791968768fe501efaJames Dong
1523134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            // printf("*** coding='%s' width=%d height=%d\n",
1524134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            //        chunk, width, height);
152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1526f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1527f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1528f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
1530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // if the chunk type is encv, we'll get the type from the sinf/frma box later
1531ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1532ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyWidth, width);
153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyHeight, height);
153520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1536c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
153720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + sizeof(buffer);
153820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
153920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
154020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
154120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
154220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
154320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1544bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1545bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1546bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1547bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
154920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
155020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
155120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'c', 'o'):
155220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('c', 'o', '6', '4'):
155320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1554274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1555274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1556274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
155720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
155820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setChunkOffsetParams(
155920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
156020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15610517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
15620517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
156320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
156720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
156820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
156920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
157020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'c'):
157120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1572274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1573274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1574274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
157520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
157620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleToChunkParams(
157720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
157820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15790517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
15800517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
158420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
158520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
158620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
158720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
158820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'z'):
158920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'z', '2'):
159020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1591274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1592274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1593274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
159420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
159520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleSizeParams(
159620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
159720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15980517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
15990517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
160020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
160120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
160220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
160320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1604738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            size_t max_size;
160549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
160649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber
160749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            if (err != OK) {
160849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber                return err;
160949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            }
1610738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
161105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (max_size != 0) {
161205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // Assume that a given buffer only contains at most 10 chunks,
161305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // each chunk originally prefixed with a 2 byte length will
161405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
161505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // and thus will grow by 2 bytes per chunk.
1616beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                if (max_size > SIZE_MAX - 10 * 2) {
1617beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    ALOGE("max sample size too big: %zu", max_size);
1618beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    return ERROR_MALFORMED;
1619beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                }
162005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
162105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            } else {
162205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // No size was specified. Pick a conservatively large size.
1623beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                uint32_t width, height;
1624beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) ||
1625beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) {
162605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    ALOGE("No width or height, assuming worst case 1080p");
1627f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    width = 1920;
1628f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    height = 1080;
1629beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                } else {
1630beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // A resolution was specified, check that it's not too big. The values below
1631beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // were chosen so that the calculations below don't cause overflows, they're
1632beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // not indicating that resolutions up to 32kx32k are actually supported.
1633beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    if (width > 32768 || height > 32768) {
1634beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                        ALOGE("can't support %u x %u video", width, height);
1635beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                        return ERROR_MALFORMED;
1636beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    }
163705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
1638f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar
16394256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen                const char *mime;
16404256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
164107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
164207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
164307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    // AVC & HEVC requires compression ratio of at least 2, and uses
1644f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // macroblocks
1645f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192;
1646f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                } else {
1647f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // For all other formats there is no minimum compression
1648f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // ratio. Use compression ratio of 1.
1649f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    max_size = width * height * 3 / 2;
165005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
1651f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
165205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
1653113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong
16544256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen            // NOTE: setting another piece of metadata invalidates any pointers (such as the
16554256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen            // mimetype) previously obtained, so don't cache them.
1656113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            const char *mime;
1657113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1658113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            // Calculate average frame rate.
1659113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            if (!strncasecmp("video/", mime, 6)) {
1660113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                size_t nSamples = mLastTrack->sampleTable->countSamples();
1661949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                if (nSamples == 0) {
1662949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    int32_t trackId;
1663949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
1664949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        for (size_t i = 0; i < mTrex.size(); i++) {
1665949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            Trex *t = &mTrex.editItemAt(i);
1666949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            if (t->track_ID == (uint32_t) trackId) {
1667949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                if (t->default_sample_duration > 0) {
1668949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                    int32_t frameRate =
1669949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                            mLastTrack->timescale / t->default_sample_duration;
1670949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                    mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1671949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                }
1672949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                break;
1673949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            }
1674949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        }
1675949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    }
1676949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                } else {
1677949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    int64_t durationUs;
1678949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
1679949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        if (durationUs > 0) {
1680949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            int32_t frameRate = (nSamples * 1000000LL +
1681949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                        (durationUs >> 1)) / durationUs;
1682949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1683949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        }
1684113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                    }
1685113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                }
1686113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            }
1687113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong
168820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
168920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
169020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
169120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 't', 's'):
169220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1693274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1694274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1695274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
16960517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16970517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
169820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
169920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setTimeToSampleParams(
170020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
170120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
170220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
170320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
170420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
170520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
170620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
170720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
170820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        case FOURCC('c', 't', 't', 's'):
17104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        {
1711274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1712274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1713274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
17140517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
17164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            status_t err =
17174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                mLastTrack->sampleTable->setCompositionTimeToSampleParams(
17184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                        data_offset, chunk_data_size);
17194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
17204931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            if (err != OK) {
17214931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                return err;
17224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            }
17234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
17244931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            break;
17254931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        }
17264931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 's'):
172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1729274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1730274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1731274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
17320517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17330517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
173420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
173520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSyncSampleParams(
173620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
173720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
173820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
173920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
174020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
174120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
174220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
174320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
174420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1745afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        // \xA9xyz
1746e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh        case FOURCC(0xA9, 'x', 'y', 'z'):
17474948818cb91176df74c972ac27b2f392b5d148bcJames Dong        {
17480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17490517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1750afd492436efc7f66b958da14659b52232efa5910Marco Nelissen            // Best case the total data length inside "\xA9xyz" box
1751afd492436efc7f66b958da14659b52232efa5910Marco Nelissen            // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/",
17524948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // where "\x00\x04" is the text string length with value = 4,
17534948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // "\0x15\xc7" is the language code = en, and "0+0" is a
17544948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // location (string) value with longitude = 0 and latitude = 0.
17554948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (chunk_data_size < 8) {
17564948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_MALFORMED;
17574948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17584948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17594948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // Worst case the location string length would be 18,
17604948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // for instance +90.0000-180.0000, without the trailing "/" and
176123b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney            // the string length + language code, and some devices include
176223b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney            // an additional 8 bytes of altitude, e.g. +007.186
176323b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney            char buffer[18 + 8];
17644948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17654948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // Substracting 5 from the data size is because the text string length +
17664948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
17674948818cb91176df74c972ac27b2f392b5d148bcJames Dong            off64_t location_length = chunk_data_size - 5;
17684948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (location_length >= (off64_t) sizeof(buffer)) {
17694948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_MALFORMED;
17704948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17714948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17724948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (mDataSource->readAt(
17734948818cb91176df74c972ac27b2f392b5d148bcJames Dong                        data_offset + 4, buffer, location_length) < location_length) {
17744948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_IO;
17754948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17764948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17774948818cb91176df74c972ac27b2f392b5d148bcJames Dong            buffer[location_length] = '\0';
17784948818cb91176df74c972ac27b2f392b5d148bcJames Dong            mFileMetaData->setCString(kKeyLocation, buffer);
17794948818cb91176df74c972ac27b2f392b5d148bcJames Dong            break;
17804948818cb91176df74c972ac27b2f392b5d148bcJames Dong        }
17814948818cb91176df74c972ac27b2f392b5d148bcJames Dong
178220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('e', 's', 'd', 's'):
178320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
17840517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17850517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
178620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 4) {
178720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
178820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
178920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
179020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[256];
1791c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            if (chunk_data_size > (off64_t)sizeof(buffer)) {
179220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
179320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
179420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
179534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
179620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
179720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
179820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
179920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
180020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
180120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
180220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
180320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
180420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1805f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1806f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1807f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
180820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
181020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1811ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            if (mPath.size() >= 2
1812ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1813ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // Information from the ESDS must be relied on for proper
1814ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // setup of sample rate and channel count for MPEG4 Audio.
1815ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // The generic header appears to only contain generic
1816ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // information...
1817ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1818ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1819ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        &buffer[4], chunk_data_size - 4);
1820ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1821ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                if (err != OK) {
1822ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    return err;
1823ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                }
1824ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            }
1825ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            if (mPath.size() >= 2
1826ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) {
1827ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                // Check if the video is MPEG2
1828ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                ESDS esds(&buffer[4], chunk_data_size - 4);
1829ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar
1830ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                uint8_t objectTypeIndication;
1831ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) {
1832ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) {
1833ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
1834ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    }
1835ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                }
1836ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            }
183720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
183820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
183920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
184046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        case FOURCC('b', 't', 'r', 't'):
184146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        {
184246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            *offset += chunk_size;
1843fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa            if (mLastTrack == NULL) {
1844fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa                return ERROR_MALFORMED;
1845fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa            }
184646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
184746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint8_t buffer[12];
184846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (chunk_data_size != sizeof(buffer)) {
184946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                return ERROR_MALFORMED;
185046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
185146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
185246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (mDataSource->readAt(
185346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
185446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                return ERROR_IO;
185546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
185646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
185746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint32_t maxBitrate = U32_AT(&buffer[4]);
185846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint32_t avgBitrate = U32_AT(&buffer[8]);
185946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
186046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
186146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
186246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
186346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
186446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
186546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            break;
186646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        }
186720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
186820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', 'C'):
186920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
18700517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
18710517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1872d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
187320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18746a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            if (buffer->data() == NULL) {
18756a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                ALOGE("b/28471206");
18766a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                return NO_MEMORY;
18776a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            }
18786a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen
187934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
1880d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
188120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
188220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
188320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1884f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1885f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1886f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
188720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
1888d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson                    kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size);
188920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
189020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
189120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
18923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', 'C'):
18933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        {
18943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
18953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
18966a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            if (buffer->data() == NULL) {
18976a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                ALOGE("b/28471206");
18986a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                return NO_MEMORY;
18996a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            }
19006a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen
19013b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            if (mDataSource->readAt(
19023b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
19033b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                return ERROR_IO;
19043b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
19053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
1906f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1907f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1908f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
19093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            mLastTrack->meta->setData(
19103b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                    kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size);
19113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
19123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            *offset += chunk_size;
19133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            break;
19143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
191520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1916244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        case FOURCC('d', '2', '6', '3'):
1917244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        {
19180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
191917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            /*
192017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * d263 contains a fixed 7 bytes part:
192117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   vendor - 4 bytes
192217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   version - 1 byte
192317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   level - 1 byte
192417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   profile - 1 byte
192517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * optionally, "d263" box itself may contain a 16-byte
192617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * bit rate box (bitr)
192717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   average bit rate - 4 bytes
192817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   max bit rate - 4 bytes
192917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             */
193017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            char buffer[23];
193117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            if (chunk_data_size != 7 &&
193217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong                chunk_data_size != 23) {
1933ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size);
1934244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                return ERROR_MALFORMED;
1935244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            }
1936244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1937244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            if (mDataSource->readAt(
1938244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
1939244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                return ERROR_IO;
1940244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            }
1941244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1942f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1943f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1944f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1945244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
1946244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1947244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            break;
1948244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        }
1949244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
195072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'e', 't', 'a'):
195172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
19528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            off64_t stop_offset = *offset + chunk_size;
19538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            *offset = data_offset;
19548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            bool isParsingMetaKeys = underQTMetaPath(mPath, 2);
19558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (!isParsingMetaKeys) {
19568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                uint8_t buffer[4];
19578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (chunk_data_size < (off64_t)sizeof(buffer)) {
19588ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return ERROR_MALFORMED;
19608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
1961bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
19628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (mDataSource->readAt(
19638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                            data_offset, buffer, 4) < 4) {
19648ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return ERROR_IO;
19668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
196772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
19688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (U32_AT(buffer) != 0) {
19698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // Should be version 0, flags 0.
1970ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
19718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // If it's not, let's assume this is one of those
19728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // apparently malformed chunks that don't have flags
19738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // and completely different semantics than what's
19748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // in the MPEG4 specs and skip it.
19758ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return OK;
19778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
19788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                *offset +=  sizeof(buffer);
197972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
198072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
198172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            while (*offset < stop_offset) {
198272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                status_t err = parseChunk(offset, depth + 1);
198372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
198472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
198572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
198672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
1987bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1988bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1989bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1990bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
199172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
199272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
199372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
19945d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('m', 'e', 'a', 'n'):
19955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('n', 'a', 'm', 'e'):
199672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('d', 'a', 't', 'a'):
199772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
19980517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
19990517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
200072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
2001fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                status_t err = parseITunesMetaData(data_offset, chunk_data_size);
200272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
200372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
200472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
200572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
200672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
200772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
200872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
200972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
201072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
201172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'v', 'h', 'd'):
201272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
20130517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
20140517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
20150d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen            if (depth != 1) {
20160d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                ALOGE("mvhd: depth %d", depth);
20170d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                return ERROR_MALFORMED;
20180d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen            }
2019c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 32) {
202072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_MALFORMED;
202172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
202272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint8_t header[32];
202472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mDataSource->readAt(
202572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                        data_offset, header, sizeof(header))
202672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    < (ssize_t)sizeof(header)) {
202772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_IO;
202872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
202972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2030fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen            uint64_t creationTime;
2031c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint64_t duration = 0;
203272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (header[0] == 1) {
203372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U64_AT(&header[4]);
2034fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                mHeaderTimescale = U32_AT(&header[20]);
2035c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = U64_AT(&header[24]);
2036c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration == 0xffffffffffffffff) {
2037c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = 0;
2038c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2039bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (header[0] != 0) {
2040bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
204172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            } else {
204272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U32_AT(&header[4]);
2043fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                mHeaderTimescale = U32_AT(&header[12]);
2044c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                uint32_t d32 = U32_AT(&header[16]);
2045c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (d32 == 0xffffffff) {
2046c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    d32 = 0;
2047c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2048c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = d32;
2049c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
20503724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
2051c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
205272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
205372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
205472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            String8 s;
20553724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            if (convertTimeToDate(creationTime, &s)) {
20563724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen                mFileMetaData->setCString(kKeyDate, s.string());
20573724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            }
205872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
205972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
206072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
206172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
206272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2063c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        case FOURCC('m', 'e', 'h', 'd'):
2064c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        {
2065c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            *offset += chunk_size;
2066c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2067c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 8) {
2068c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_MALFORMED;
2069c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2070c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2071c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint8_t flags[4];
2072c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (mDataSource->readAt(
2073c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                        data_offset, flags, sizeof(flags))
2074c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    < (ssize_t)sizeof(flags)) {
2075c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2076c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2077c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2078c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint64_t duration = 0;
2079c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (flags[0] == 1) {
2080c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                // 64 bit
2081c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (chunk_data_size < 12) {
2082c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    return ERROR_MALFORMED;
2083c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2084c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mDataSource->getUInt64(data_offset + 4, &duration);
2085c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration == 0xffffffffffffffff) {
2086c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = 0;
2087c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2088c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            } else if (flags[0] == 0) {
2089c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                // 32 bit
2090c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                uint32_t d32;
2091c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mDataSource->getUInt32(data_offset + 4, &d32);
2092c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (d32 == 0xffffffff) {
2093c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    d32 = 0;
2094c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2095c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = d32;
2096c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            } else {
2097c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_MALFORMED;
2098c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2099c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2100e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake            if (duration != 0 && mHeaderTimescale != 0) {
2101c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
2102c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2103c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2104c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            break;
2105c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
2106c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2107dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        case FOURCC('m', 'd', 'a', 't'):
2108dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        {
2109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("mdat chunk, drm: %d", mIsDrm);
2110928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
2111928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            mMdatFound = true;
2112928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
2113dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (!mIsDrm) {
2114dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                *offset += chunk_size;
2115dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                break;
2116dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
2117dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2118dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (chunk_size < 8) {
2119dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
2120dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
2121dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return parseDrmSINF(offset, data_offset);
2123dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
2124dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
21253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        case FOURCC('h', 'd', 'l', 'r'):
21263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        {
21270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
21280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2129ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang            if (underQTMetaPath(mPath, 3)) {
2130ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                break;
2131ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang            }
2132ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang
21333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t buffer;
21343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (mDataSource->readAt(
21353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                        data_offset + 8, &buffer, 4) < 4) {
21363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                return ERROR_IO;
21373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t type = ntohl(buffer);
21403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            // For the 3GPP file format, the handler-type within the 'hdlr' box
2141e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            // shall be 'text'. We also want to support 'sbtl' handler type
2142e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            // for a practical reason as various MPEG4 containers use it.
2143e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
2144cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                if (mLastTrack != NULL) {
2145cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                    mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
2146cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                }
21473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            break;
21503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        }
21513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        case FOURCC('k', 'e', 'y', 's'):
21538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        {
21548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            *offset += chunk_size;
21558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
21568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (underQTMetaPath(mPath, 3)) {
2157ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                status_t err = parseQTMetaKey(data_offset, chunk_data_size);
2158ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                if (err != OK) {
2159ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    return err;
2160ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                }
21618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            }
21628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            break;
21638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
21648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
2165c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        case FOURCC('t', 'r', 'e', 'x'):
2166c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        {
2167c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            *offset += chunk_size;
2168c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2169c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 24) {
2170c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2171c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2172c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            Trex trex;
2173c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) ||
2174c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) ||
2175c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) ||
2176c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) ||
2177c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) {
2178c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2179c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2180c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mTrex.add(trex);
2181c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            break;
2182c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
2183c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
21847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        case FOURCC('t', 'x', '3', 'g'):
21857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        {
2186f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
2187f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
2188f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
21893b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t type;
21903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            const void *data;
21913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            size_t size = 0;
21923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (!mLastTrack->meta->findData(
21933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    kKeyTextFormatData, &type, &data, &size)) {
21943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                size = 0;
21953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21970e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich            if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
2198dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake                return ERROR_MALFORMED;
2199dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake            }
2200dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake
22018da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
22028da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (buffer == NULL) {
22038da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
22048da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
22053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (size > 0) {
22073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                memcpy(buffer, data, size);
22083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
22093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
22113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    < chunk_size) {
22123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                delete[] buffer;
22133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                buffer = NULL;
22143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen                // advance read pointer so we don't end up reading this again
22160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen                *offset += chunk_size;
22173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                return ERROR_IO;
22183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
22193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            mLastTrack->meta->setData(
22213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    kKeyTextFormatData, 0, buffer, size + chunk_size);
22223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            delete[] buffer;
22247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
22257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            *offset += chunk_size;
22267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            break;
22277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
22287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2229515e855eae78aa495da58356486aaa666cb57fd1James Dong        case FOURCC('c', 'o', 'v', 'r'):
2230515e855eae78aa495da58356486aaa666cb57fd1James Dong        {
22310517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
22320517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2233515e855eae78aa495da58356486aaa666cb57fd1James Dong            if (mFileMetaData != NULL) {
2234635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64,
2235635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                      chunk_data_size, data_offset);
22361e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake
2237635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) {
22381e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake                    return ERROR_MALFORMED;
22391e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake                }
22401552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
22416a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                if (buffer->data() == NULL) {
22426a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                    ALOGE("b/28471206");
22436a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                    return NO_MEMORY;
22446a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                }
2245515e855eae78aa495da58356486aaa666cb57fd1James Dong                if (mDataSource->readAt(
22461552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                    data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
2247515e855eae78aa495da58356486aaa666cb57fd1James Dong                    return ERROR_IO;
2248515e855eae78aa495da58356486aaa666cb57fd1James Dong                }
2249515e855eae78aa495da58356486aaa666cb57fd1James Dong                const int kSkipBytesOfDataBox = 16;
225097d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                if (chunk_data_size <= kSkipBytesOfDataBox) {
225197d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                    return ERROR_MALFORMED;
225297d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                }
225397d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake
2254515e855eae78aa495da58356486aaa666cb57fd1James Dong                mFileMetaData->setData(
2255515e855eae78aa495da58356486aaa666cb57fd1James Dong                    kKeyAlbumArt, MetaData::TYPE_NONE,
22561552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                    buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
2257515e855eae78aa495da58356486aaa666cb57fd1James Dong            }
2258515e855eae78aa495da58356486aaa666cb57fd1James Dong
2259515e855eae78aa495da58356486aaa666cb57fd1James Dong            break;
2260515e855eae78aa495da58356486aaa666cb57fd1James Dong        }
2261515e855eae78aa495da58356486aaa666cb57fd1James Dong
226258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        case FOURCC('c', 'o', 'l', 'r'):
226358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        {
226458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            *offset += chunk_size;
226558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
226658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            // ignore otherwise
226758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
226858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                status_t err = parseColorInfo(data_offset, chunk_data_size);
226958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                if (err != OK) {
227058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                    return err;
227158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                }
227258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            }
227358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
227458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            break;
227558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        }
227658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
2277fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('t', 'i', 't', 'l'):
2278fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('p', 'e', 'r', 'f'):
2279fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'u', 't', 'h'):
2280fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('g', 'n', 'r', 'e'):
2281fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'l', 'b', 'm'):
2282fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('y', 'r', 'r', 'c'):
2283fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
22840517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
22850517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2286fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
2287fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2288fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (err != OK) {
2289fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                return err;
2290fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2291fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2292fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2293fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2294fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2295328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        case FOURCC('I', 'D', '3', '2'):
2296328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        {
22970517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
22980517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2299328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            if (chunk_data_size < 6) {
2300328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                return ERROR_MALFORMED;
2301328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            }
2302328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2303328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            parseID3v2MetaData(data_offset + 6);
2304328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2305328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            break;
2306328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
2307328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
23085d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('-', '-', '-', '-'):
23095d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        {
23105d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentMean.clear();
23115d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentName.clear();
23125d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentData.clear();
23135d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            *offset += chunk_size;
23145d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            break;
23155d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        }
23165d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen
231705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('s', 'i', 'd', 'x'):
231805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        {
2319ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseSegmentIndex(data_offset, chunk_data_size);
2320ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
2321ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
2322ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
232305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset += chunk_size;
232405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return UNKNOWN_ERROR; // stop parsing after sidx
232505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
232605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2327bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        case FOURCC('a', 'c', '-', '3'):
2328bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        {
2329bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa            *offset += chunk_size;
2330bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa            return parseAC3SampleEntry(data_offset);
2331bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        }
2332bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2333bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        case FOURCC('f', 't', 'y', 'p'):
2334bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        {
2335bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            if (chunk_data_size < 8 || depth != 0) {
2336bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                return ERROR_MALFORMED;
2337bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
2338bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2339bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            off64_t stop_offset = *offset + chunk_size;
2340bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4;
2341bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
2342bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (i == 1) {
2343bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    // Skip this index, it refers to the minorVersion,
2344bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    // not a brand.
2345bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    continue;
2346bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
2347bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2348bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                uint32_t brand;
2349bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (mDataSource->readAt(data_offset + 4 * i, &brand, 4) < 4) {
2350bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    return ERROR_MALFORMED;
2351bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
2352bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2353bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                brand = ntohl(brand);
2354bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (brand == FOURCC('q', 't', ' ', ' ')) {
2355bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    mIsQT = true;
2356bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    break;
2357bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
2358bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
2359bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2360bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            *offset = stop_offset;
2361bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2362bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            break;
2363bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        }
2364bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
236520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
236620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
23678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            // check if we're parsing 'ilst' for meta keys
23688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            // if so, treat type as a number (key-id).
23698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (underQTMetaPath(mPath, 3)) {
2370ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
2371ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                if (err != OK) {
2372ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    return err;
2373ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                }
23748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            }
23758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
237620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
237720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
237820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
237920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
238020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
238120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
238220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
238320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2384bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasastatus_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) {
2385bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip 16 bytes:
2386bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 6-byte reserved,
2387bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte data reference index,
2388bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 8-byte reserved
2389bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 16;
2390bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint16_t channelCount;
2391bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt16(offset, &channelCount)) {
2392bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2393bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2394bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip 8 bytes:
2395bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte channelCount,
2396bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte sample size,
2397bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 4-byte reserved
2398bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 8;
2399bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint16_t sampleRate;
2400bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt16(offset, &sampleRate)) {
2401bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate");
2402bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2403bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2404bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2405bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip 4 bytes:
2406bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte sampleRate,
2407bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte reserved
2408bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 4;
2409bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    return parseAC3SpecificBox(offset, sampleRate);
2410bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa}
2411bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2412bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasastatus_t MPEG4Extractor::parseAC3SpecificBox(
2413bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        off64_t offset, uint16_t sampleRate) {
2414bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint32_t size;
2415bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // + 4-byte size
2416bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // + 4-byte type
2417bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // + 3-byte payload
2418bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    const uint32_t kAC3SpecificBoxSize = 11;
2419bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt32(offset, &size) || size < kAC3SpecificBoxSize) {
2420bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read specific box size");
2421bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2422bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2423bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2424bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 4;
2425bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint32_t type;
2426bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'a', 'c', '3')) {
2427bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3");
2428bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2429bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2430bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2431bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 4;
2432bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    const uint32_t kAC3SpecificBoxPayloadSize = 3;
2433bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint8_t chunk[kAC3SpecificBoxPayloadSize];
2434bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (mDataSource->readAt(offset, chunk, sizeof(chunk)) != sizeof(chunk)) {
2435bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 specific block: bitstream fields");
2436bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2437bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2438bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2439bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    ABitReader br(chunk, sizeof(chunk));
2440bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
2441bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    static const unsigned sampleRateTable[] = {48000, 44100, 32000};
2442bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2443bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned fscod = br.getBits(2);
2444bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (fscod == 3) {
2445bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("Incorrect fscod (3) in AC3 header");
2446bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2447bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2448bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned boxSampleRate = sampleRateTable[fscod];
2449bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (boxSampleRate != sampleRate) {
2450bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
2451bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa            boxSampleRate, sampleRate);
2452bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2453bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2454bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2455bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned bsid = br.getBits(5);
2456bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (bsid > 8) {
2457bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
2458bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2459bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2460bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2461bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip
2462bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned bsmod __unused = br.getBits(3);
2463bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2464bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned acmod = br.getBits(3);
2465bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned lfeon = br.getBits(1);
2466bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned channelCount = channelCountTable[acmod] + lfeon;
2467bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2468bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (mLastTrack == NULL) {
2469bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2470bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2471bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
2472bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    mLastTrack->meta->setInt32(kKeyChannelCount, channelCount);
2473bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
2474bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    return OK;
2475bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa}
2476bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
247705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
247805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen  ALOGV("MPEG4Extractor::parseSegmentIndex");
247905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
248005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 12) {
248105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      return -EINVAL;
248205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
248305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
248405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
248505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) {
248605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
248705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
248805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
248905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t version = flags >> 24;
249005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    flags &= 0xffffff;
249105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
249205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("sidx version %d", version);
249305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
249405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t referenceId;
249505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
249605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
249705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
249805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
249905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t timeScale;
250005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
250105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
250205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
250305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
2504e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake    if (timeScale == 0)
2505e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake        return ERROR_MALFORMED;
250605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
250705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t earliestPresentationTime;
250805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t firstOffset;
250905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
251005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 12;
251105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 12;
251205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
251305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (version == 0) {
251405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 8) {
251505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
251605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
251705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t tmp;
251805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
251905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
252005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
252105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        earliestPresentationTime = tmp;
252205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset + 4, &tmp)) {
252305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
252405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
252505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        firstOffset = tmp;
252605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 8;
252705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 8;
252805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
252905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 16) {
253005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
253105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
253205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
253305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
253405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
253505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
253605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
253705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
253805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 16;
253905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 16;
254005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
2541a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset);
254205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
254305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 4) {
254405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
254505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
254605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
254705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint16_t referenceCount;
254805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
254905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
255005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
255105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 4;
255205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 4;
255305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("refcount: %d", referenceCount);
255405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
255505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < referenceCount * 12) {
255605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
255705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
255805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
255905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t total_duration = 0;
256005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    for (unsigned int i = 0; i < referenceCount; i++) {
256105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t d1, d2, d3;
256205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
256305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &d1) ||     // size
256405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            !mDataSource->getUInt32(offset + 4, &d2) || // duration
256505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            !mDataSource->getUInt32(offset + 8, &d3)) { // flags
256605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
256705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
256805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
256905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (d1 & 0x80000000) {
257005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGW("sub-sidx boxes not supported yet");
257105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
257205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bool sap = d3 & 0x80000000;
25733f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen        uint32_t saptype = (d3 >> 28) & 7;
25743f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen        if (!sap || (saptype != 1 && saptype != 2)) {
25753f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            // type 1 and 2 are sync samples
25763f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            ALOGW("not a stream access point, or unsupported type: %08x", d3);
257705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
257805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        total_duration += d2;
257905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 12;
258005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
258105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        SidxEntry se;
258205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        se.mSize = d1 & 0x7fffffff;
258305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        se.mDurationUs = 1000000LL * d2 / timeScale;
258405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mSidxEntries.add(se);
258505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
258605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2587c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    uint64_t sidxDuration = total_duration * 1000000 / timeScale;
258805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2589f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
2590f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
2591f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
259205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t metaDuration;
259305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
2594c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        mLastTrack->meta->setInt64(kKeyDuration, sidxDuration);
259505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
259605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
259705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
259805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
25998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) {
26008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (size < 8) {
26018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t count;
26058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 4, &count)) {
26068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (mMetaKeyMap.size() > 0) {
26108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        ALOGW("'keys' atom seen again, discarding existing entries");
26118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        mMetaKeyMap.clear();
26128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    off64_t keyOffset = offset + 8;
26158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    off64_t stopOffset = offset + size;
26168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    for (size_t i = 1; i <= count; i++) {
26178cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (keyOffset + 8 > stopOffset) {
26188cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26198cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26208cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26218cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t keySize;
26228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(keyOffset, &keySize)
26238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || keySize < 8
26248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || keyOffset + keySize > stopOffset) {
26258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t type;
26298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(keyOffset + 4, &type)
26308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || type != FOURCC('m', 'd', 't', 'a')) {
26318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keySize -= 8;
26358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keyOffset += 8;
26368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        sp<ABuffer> keyData = new ABuffer(keySize);
26388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (keyData->data() == NULL) {
26398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26418cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (mDataSource->readAt(
26428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                keyOffset, keyData->data(), keySize) < (ssize_t) keySize) {
26438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        AString key((const char *)keyData->data(), keySize);
26478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        mMetaKeyMap.add(i, key);
26488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keyOffset += keySize;
26508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return OK;
26528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
26538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal(
26558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        int32_t keyId, off64_t offset, size_t size) {
26568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    ssize_t index = mMetaKeyMap.indexOfKey(keyId);
26578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (index < 0) {
26588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // corresponding key is not present, ignore
26598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
266105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
26628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (size <= 16) {
26638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t dataSize;
26668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset, &dataSize)
26678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || dataSize > size || dataSize <= 16) {
26688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t atomFourCC;
26718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
26728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || atomFourCC != FOURCC('d', 'a', 't', 'a')) {
26738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t dataType;
26768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 8, &dataType)
26778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || ((dataType & 0xff000000) != 0)) {
26788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // not well-known type
26798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    dataSize -= 16;
26838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    offset += 16;
26848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (dataType == 23 && dataSize >= 4) {
26868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // BE Float32
26878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t val;
26888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(offset, &val)) {
26898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
26928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val);
26938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26944dbff11975e737482537e1636051690188f3fbc4Praveen Chavan    } else if (dataType == 67 && dataSize >= 4) {
26954dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        // BE signed int32
26964dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        uint32_t val;
26974dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        if (!mDataSource->getUInt32(offset, &val)) {
26984dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            return ERROR_MALFORMED;
26994dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        }
27004dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
27014dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            mFileMetaData->setInt32(kKeyTemporalLayerCount, val);
27024dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        }
27038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    } else {
27048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // add more keys if needed
27058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
27068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
27078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
27088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return OK;
27098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
271005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2711ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader(
2712c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, off64_t data_size) {
2713ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (data_size < 4) {
2714ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
2715ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2716ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2717ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t version;
2718ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(data_offset, &version, 1) < 1) {
2719ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
2720ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2721ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2722ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t dynSize = (version == 1) ? 36 : 24;
2723ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2724ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t buffer[36 + 60];
2725ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2726c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    if (data_size != (off64_t)dynSize + 60) {
2727ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
2728ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2729ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2730ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(
2731ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                data_offset, buffer, data_size) < (ssize_t)data_size) {
2732ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
2733ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2734ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2735b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    uint64_t ctime __unused, mtime __unused, duration __unused;
2736ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t id;
2737ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2738ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (version == 1) {
2739ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U64_AT(&buffer[4]);
2740ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U64_AT(&buffer[12]);
2741ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[20]);
2742ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U64_AT(&buffer[28]);
274304022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen    } else if (version == 0) {
2744ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U32_AT(&buffer[4]);
2745ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U32_AT(&buffer[8]);
2746ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[12]);
2747ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U32_AT(&buffer[20]);
274804022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen    } else {
274904022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen        return ERROR_UNSUPPORTED;
2750ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2751ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2752f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
2753f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
2754f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
2755ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    mLastTrack->meta->setInt32(kKeyTrackID, id);
2756ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2757ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t matrixOffset = dynSize + 16;
2758ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a00 = U32_AT(&buffer[matrixOffset]);
2759ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
2760ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
2761ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
2762ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2763ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0
2764b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
2765b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
2766b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe
2767df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("x' = %.2f * x + %.2f * y + %.2f",
2768ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
2769df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("y' = %.2f * x + %.2f * y + %.2f",
2770ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
2771ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif
2772ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2773ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t rotationDegrees;
2774ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2775ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    static const int32_t kFixedOne = 0x10000;
2776ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
2777ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        // Identity, no rotation
2778ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
2779ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
2780ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 90;
2781ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
2782ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 270;
2783ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
2784ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 180;
2785ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
27865ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("We only support 0,90,180,270 degree rotation matrices");
2787ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
2788ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2789ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2790ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (rotationDegrees != 0) {
2791ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
2792ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2793ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2794b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    // Handle presentation display size, which could be different
2795b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    // from the image size indicated by kKeyWidth and kKeyHeight.
2796ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t width = U32_AT(&buffer[dynSize + 52]);
2797ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t height = U32_AT(&buffer[dynSize + 56]);
2798b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
2799b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
2800ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2801ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    return OK;
2802ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber}
2803ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2804fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
2805c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich    if (size < 4 || size == SIZE_MAX) {
280672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_MALFORMED;
280772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
280872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
28098da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
28108da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (buffer == NULL) {
28118da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
28128da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
281372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (mDataSource->readAt(
281472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                offset, buffer, size) != (ssize_t)size) {
281572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        delete[] buffer;
281672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        buffer = NULL;
281772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
281872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_IO;
281972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
282072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
282172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t flags = U32_AT(buffer);
282272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
282372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t metadataKey = 0;
28245d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen    char chunk[5];
28255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen    MakeFourCCString(mPath[4], chunk);
2826ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("meta: %s @ %lld", chunk, (long long)offset);
28272d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer    switch ((int32_t)mPath[4]) {
282872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'a', 'l', 'b'):
282972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
283072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbum;
283172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
283272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
283372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'A', 'R', 'T'):
283472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
283572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyArtist;
283672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
283772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
283866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        case FOURCC('a', 'A', 'R', 'T'):
283966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        {
284066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            metadataKey = kKeyAlbumArtist;
284166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            break;
284266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        }
284372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'd', 'a', 'y'):
284472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
284572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyYear;
284672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
284772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
284872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'n', 'a', 'm'):
284972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
285072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyTitle;
285172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
285272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
285372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'w', 'r', 't'):
285472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
285572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyWriter;
285672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
285772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
285872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('c', 'o', 'v', 'r'):
285972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
286072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbumArt;
286172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
286272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
286372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('g', 'n', 'r', 'e'):
286472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
286572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyGenre;
286672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
286772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
286826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC(0xa9, 'g', 'e', 'n'):
286926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
287026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            metadataKey = kKeyGenre;
287126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
287226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
287311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        case FOURCC('c', 'p', 'i', 'l'):
287411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        {
287511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            if (size == 9 && flags == 21) {
287611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                char tmp[16];
287711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                sprintf(tmp, "%d",
287811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                        (int)buffer[size - 1]);
287911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen
288011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                mFileMetaData->setCString(kKeyCompilation, tmp);
288111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            }
288211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            break;
288311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        }
288472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('t', 'r', 'k', 'n'):
288572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
288672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (size == 16 && flags == 0) {
288772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char tmp[16];
2888afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTrack = (uint16_t*)&buffer[10];
2889afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
2890afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
289172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
289272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
289372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
289472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
289572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
289626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC('d', 'i', 's', 'k'):
289726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
2898afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik            if ((size == 14 || size == 16) && flags == 0) {
289926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                char tmp[16];
2900afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pDisc = (uint16_t*)&buffer[10];
2901afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
2902afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
290326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
290426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(kKeyDiscNumber, tmp);
290526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            }
290626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
290726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
29085d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('-', '-', '-', '-'):
29095d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        {
29105d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            buffer[size] = '\0';
29115d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            switch (mPath[5]) {
29125d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('m', 'e', 'a', 'n'):
29135d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentMean.setTo((const char *)buffer + 4);
29145d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
29155d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('n', 'a', 'm', 'e'):
29165d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentName.setTo((const char *)buffer + 4);
29175d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
29185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('d', 'a', 't', 'a'):
29195cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                    if (size < 8) {
29205cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        delete[] buffer;
29215cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        buffer = NULL;
29225cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        ALOGE("b/24346430");
29235cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        return ERROR_MALFORMED;
29245cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                    }
29255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentData.setTo((const char *)buffer + 8);
29265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
29275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            }
29288c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
29298c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // Once we have a set of mean/name/data info, go ahead and process
29308c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // it to see if its something we are interested in.  Whether or not
29318c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // were are interested in the specific tag, make sure to clear out
29328c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // the set so we can be ready to process another tuple should one
29338c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // show up later in the file.
29348c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            if ((mLastCommentMean.length() != 0) &&
29358c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                (mLastCommentName.length() != 0) &&
29368c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                (mLastCommentData.length() != 0)) {
29378c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
29388c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                if (mLastCommentMean == "com.apple.iTunes"
29398c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        && mLastCommentName == "iTunSMPB") {
29408c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    int32_t delay, padding;
29418c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    if (sscanf(mLastCommentData,
29428c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                               " %*x %x %x %*x", &delay, &padding) == 2) {
2943f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                        if (mLastTrack == NULL)
2944f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                            return ERROR_MALFORMED;
2945f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
29468c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
29478c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
29488c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    }
29495d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                }
29508c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
29515d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentMean.clear();
29525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentName.clear();
29535d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentData.clear();
29545d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            }
29555d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            break;
29565d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        }
295726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
295872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        default:
295972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
296072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
296172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2962328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
296372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        if (metadataKey == kKeyAlbumArt) {
296472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setData(
296572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    kKeyAlbumArt, MetaData::TYPE_NONE,
296672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    buffer + 8, size - 8);
296772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else if (metadataKey == kKeyGenre) {
296872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (flags == 0) {
296926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // uint8_t genre code, iTunes genre codes are
297026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // the standard id3 codes, except they start
297126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // at 1 instead of 0 (e.g. Pop is 14, not 13)
297226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // We use standard id3 numbering, so subtract 1.
297326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                int genrecode = (int)buffer[size - 1];
297426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                genrecode--;
297526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                if (genrecode < 0) {
297626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                    genrecode = 255; // reserved for 'unknown genre'
297726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                }
297872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char genre[10];
297926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                sprintf(genre, "%d", genrecode);
298072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
298172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(metadataKey, genre);
298226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            } else if (flags == 1) {
298326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // custom genre string
298426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                buffer[size] = '\0';
298526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
298626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(
298726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                        metadataKey, (const char *)buffer + 8);
298872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
298972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else {
299072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            buffer[size] = '\0';
299172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
299272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(
299372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    metadataKey, (const char *)buffer + 8);
299472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
299572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
299672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
299772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    delete[] buffer;
299872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    buffer = NULL;
299972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
300072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return OK;
300172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
300272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
300358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
300458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
300558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_MALFORMED;
300658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
300758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
300858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
300958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (buffer == NULL) {
301058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_MALFORMED;
301158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
301258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
301358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        delete[] buffer;
301458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        buffer = NULL;
301558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
301658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_IO;
301758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
301858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
301958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    int32_t type = U32_AT(&buffer[0]);
302058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
302151a0ff56f49faf1a19281f6d786fe18bf84794c6Hangyu Kuang            || (type == FOURCC('n', 'c', 'l', 'c') && size >= 10)) {
302258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t primaries = U16_AT(&buffer[4]);
302358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t transfer = U16_AT(&buffer[6]);
302458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t coeffs = U16_AT(&buffer[8]);
302558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);
302658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
302758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorAspects aspects;
302858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorUtils::convertIsoColorAspectsToCodecAspects(
302958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                primaries, transfer, coeffs, fullRange, aspects);
303058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
303158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        // only store the first color specification
303258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) {
303358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries);
303458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer);
303558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
303658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange);
303758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        }
303858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
303958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
304058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    delete[] buffer;
304158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    buffer = NULL;
304258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
304358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    return OK;
304458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar}
304558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
3046fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
30475cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake    if (size < 4 || size == SIZE_MAX) {
3048fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        return ERROR_MALFORMED;
3049fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3050fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
30515cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
30528da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (buffer == NULL) {
30538da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
30548da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
3055fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    if (mDataSource->readAt(
3056fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                offset, buffer, size) != (ssize_t)size) {
3057fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        delete[] buffer;
3058fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        buffer = NULL;
3059fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3060fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        return ERROR_IO;
3061fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3062fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3063fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    uint32_t metadataKey = 0;
3064fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    switch (mPath[depth]) {
3065fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('t', 'i', 't', 'l'):
3066fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3067fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyTitle;
3068fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3069fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3070fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('p', 'e', 'r', 'f'):
3071fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3072fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyArtist;
3073fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3074fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3075fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'u', 't', 'h'):
3076fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3077fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyWriter;
3078fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3079fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3080fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('g', 'n', 'r', 'e'):
3081fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3082fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyGenre;
3083fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3084fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3085fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'l', 'b', 'm'):
3086fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3087fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (buffer[size - 1] != '\0') {
3088fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              char tmp[4];
3089fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              sprintf(tmp, "%u", buffer[size - 1]);
3090fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3091fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
3092fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3093fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3094fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyAlbum;
3095fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3096fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3097fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('y', 'r', 'r', 'c'):
3098fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3099fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            char tmp[5];
3100fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            uint16_t year = U16_AT(&buffer[4]);
3101fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3102fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (year < 10000) {
3103fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                sprintf(tmp, "%u", year);
3104fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3105fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                mFileMetaData->setCString(kKeyYear, tmp);
3106fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3107fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3108fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3109fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3110fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        default:
3111fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3112fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3113fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3114fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    if (metadataKey > 0) {
3115fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        bool isUTF8 = true; // Common case
3116fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        char16_t *framedata = NULL;
3117fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        int len16 = 0; // Number of UTF-16 characters
3118fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3119fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
31209458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake        if (size < 6) {
31219458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake            return ERROR_MALFORMED;
31229458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake        }
31239458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake
3124fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        if (size - 6 >= 4) {
3125fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
3126fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            framedata = (char16_t *)(buffer + 6);
3127fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (0xfffe == *framedata) {
3128fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // endianness marker (BOM) doesn't match host endianness
3129fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                for (int i = 0; i < len16; i++) {
3130fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                    framedata[i] = bswap_16(framedata[i]);
3131fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                }
3132fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // BOM is now swapped to 0xfeff, we will execute next block too
3133fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3134fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3135fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (0xfeff == *framedata) {
3136fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // Remove the BOM
3137fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                framedata++;
3138fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                len16--;
3139fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                isUTF8 = false;
3140fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3141fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // else normal non-zero-length UTF-8 string
3142fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // we can't handle UTF-16 without BOM as there is no other
3143fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // indication of encoding.
3144fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3145fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3146fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        if (isUTF8) {
31475cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake            buffer[size] = 0;
3148fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            mFileMetaData->setCString(metadataKey, (const char *)buffer + 6);
3149fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        } else {
3150fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // Convert from UTF-16 string to UTF-8 string.
3151fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            String8 tmpUTF8str(framedata, len16);
3152fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            mFileMetaData->setCString(metadataKey, tmpUTF8str.string());
3153fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3154fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3155fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3156fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    delete[] buffer;
3157fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    buffer = NULL;
3158fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3159fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    return OK;
3160fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé}
3161fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3162328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
3163328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    ID3 id3(mDataSource, true /* ignorev1 */, offset);
3164328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3165328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (id3.isValid()) {
3166328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        struct Map {
3167328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            int key;
3168328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            const char *tag1;
3169328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            const char *tag2;
3170328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        };
3171328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        static const Map kMap[] = {
3172328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAlbum, "TALB", "TAL" },
3173328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyArtist, "TPE1", "TP1" },
3174328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAlbumArtist, "TPE2", "TP2" },
3175328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyComposer, "TCOM", "TCM" },
3176328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyGenre, "TCON", "TCO" },
3177328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyTitle, "TIT2", "TT2" },
3178328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyYear, "TYE", "TYER" },
3179328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAuthor, "TXT", "TEXT" },
3180328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyCDTrackNumber, "TRK", "TRCK" },
3181328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyDiscNumber, "TPA", "TPOS" },
3182328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyCompilation, "TCP", "TCMP" },
3183328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        };
3184328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
3185328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3186328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        for (size_t i = 0; i < kNumMapEntries; ++i) {
3187328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            if (!mFileMetaData->hasData(kMap[i].key)) {
3188328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
3189328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                if (it->done()) {
3190328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    delete it;
3191328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    it = new ID3::Iterator(id3, kMap[i].tag2);
3192328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                }
3193328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3194328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                if (it->done()) {
3195328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    delete it;
3196328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    continue;
3197328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                }
3198328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3199328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                String8 s;
3200328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                it->getString(&s);
3201328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                delete it;
3202328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3203328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                mFileMetaData->setCString(kMap[i].key, s);
3204328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            }
3205328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
3206328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3207328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        size_t dataSize;
3208328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        String8 mime;
3209328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        const void *data = id3.getAlbumArt(&dataSize, &mime);
3210328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3211328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        if (data) {
3212328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
3213328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
3214328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
3215328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    }
3216328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé}
3217328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3218b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) {
321920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
322020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
3221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return NULL;
322220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
322320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
322420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
322520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
322620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
3227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return NULL;
322820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
322920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
323020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
323120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
323220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
323320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3234371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
3235371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
3236371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
3237371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
3238c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3239c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    Trex *trex = NULL;
3240c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    int32_t trackId;
3241c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    if (track->meta->findInt32(kKeyTrackID, &trackId)) {
3242c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        for (size_t i = 0; i < mTrex.size(); i++) {
3243949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen            Trex *t = &mTrex.editItemAt(i);
3244c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (t->track_ID == (uint32_t) trackId) {
3245c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                trex = t;
3246c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                break;
3247c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
3248c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
32490386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    } else {
32500386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        ALOGE("b/21657957");
32510386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        return NULL;
3252c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    }
3253c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3254a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("getTrack called, pssh: %zu", mPssh.size());
3255ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3256a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    const char *mime;
3257a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    if (!track->meta->findCString(kKeyMIMEType, &mime)) {
3258a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        return NULL;
3259a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    }
3260a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3261a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3262a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        uint32_t type;
3263a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const void *data;
3264a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        size_t size;
3265a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) {
3266a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3267a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3268a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3269a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const uint8_t *ptr = (const uint8_t *)data;
3270a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3271a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
3272a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3273a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3274a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
3275a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        uint32_t type;
3276a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const void *data;
3277a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        size_t size;
3278a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) {
3279a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3280a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3281a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3282a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const uint8_t *ptr = (const uint8_t *)data;
3283a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3284a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (size < 22 || ptr[0] != 1) {  // configurationVersion == 1
3285a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3286a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3287a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    }
3288a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3289ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    sp<MPEG4Source> source =  new MPEG4Source(this,
329005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            track->meta, mDataSource, track->timescale, track->sampleTable,
3291c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mSidxEntries, trex, mMoofOffset);
3292ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    if (source->init() != OK) {
3293ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia        return NULL;
3294ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    }
3295ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    return source;
329620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
329720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3298bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static
3299bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) {
3300bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const char *mime;
3301bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
3302bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3303bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    uint32_t type;
3304bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const void *data;
3305bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    size_t size;
3306bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3307bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
3308bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeAVCC) {
3309bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
3310bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
33113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
33123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!track->meta->findData(kKeyHVCC, &type, &data, &size)
33133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                    || type != kTypeHVCC) {
33143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            return ERROR_MALFORMED;
33153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
3316bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
3317ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
3318bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
3319bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
3320bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeESDS) {
3321bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
3322bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
3323bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    }
3324bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3325ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih    if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
3326169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        // Make sure we have all the metadata we need.
3327ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih        ALOGE("stbl atom missing/invalid.");
3328169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        return ERROR_MALFORMED;
3329169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    }
3330169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
33312e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang    if (track->timescale == 0) {
33322e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang        ALOGE("timescale invalid.");
33332e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang        return ERROR_MALFORMED;
33342e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang    }
33352e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang
3336bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    return OK;
3337bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber}
3338bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3339f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum {
3340f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_NONE             = -1,
3341f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_NULL_OBJECT      = 0,
3342f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_MAIN         = 1, /**< Main profile                              */
3343f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_AAC_LC           = 2,   /**< Low Complexity object                     */
3344f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SSR          = 3,
3345f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_LTP          = 4,
3346f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_SBR              = 5,
3347f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SCAL         = 6,
3348f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_TWIN_VQ          = 7,
3349f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_CELP             = 8,
3350f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_HVXC             = 9,
3351f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_10          = 10, /**< (reserved)                                */
3352f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_11          = 11, /**< (reserved)                                */
3353f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_TTSI             = 12, /**< TTSI Object                               */
3354f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MAIN_SYNTH       = 13, /**< Main Synthetic object                     */
3355f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_WAV_TAB_SYNTH    = 14, /**< Wavetable Synthesis object                */
3356f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_GEN_MIDI         = 15, /**< General MIDI object                       */
3357f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
3358f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_LC        = 17,   /**< Error Resilient(ER) AAC Low Complexity    */
3359f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_18          = 18, /**< (reserved)                                */
3360f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_AAC_LTP       = 19, /**< Error Resilient(ER) AAC LTP object        */
3361f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_SCAL      = 20,   /**< Error Resilient(ER) AAC Scalable object   */
3362f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_TWIN_VQ       = 21, /**< Error Resilient(ER) TwinVQ object         */
3363f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_BSAC          = 22,   /**< Error Resilient(ER) BSAC object           */
3364f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_LD        = 23,   /**< Error Resilient(ER) AAC LowDelay object   */
3365f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_CELP          = 24, /**< Error Resilient(ER) CELP object           */
3366f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_HVXC          = 25, /**< Error Resilient(ER) HVXC object           */
3367f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_HILN          = 26, /**< Error Resilient(ER) HILN object           */
3368f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_PARA          = 27, /**< Error Resilient(ER) Parametric object     */
3369f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_28          = 28, /**< might become SSC                          */
3370f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_PS               = 29,   /**< PS, Parametric Stereo (includes SBR)      */
3371f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MPEGS            = 30, /**< MPEG Surround                             */
3372f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3373f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ESCAPE           = 31,   /**< Signal AOT uses more than 5 bits          */
3374f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3375f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L1      = 32, /**< MPEG-Layer1 in mp4                        */
3376f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L2      = 33, /**< MPEG-Layer2 in mp4                        */
3377f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L3      = 34, /**< MPEG-Layer3 in mp4                        */
3378f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_35          = 35, /**< might become DST                          */
3379f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_36          = 36, /**< might become ALS                          */
3380f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SLS          = 37, /**< AAC + SLS                                 */
3381f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_SLS              = 38, /**< SLS                                       */
3382f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_AAC_ELD       = 39, /**< AAC Enhanced Low Delay                    */
3383f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3384f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_USAC             = 42, /**< USAC                                      */
3385f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_SAOC             = 43, /**< SAOC                                      */
3386f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_LD_MPEGS         = 44, /**< Low Delay MPEG Surround                   */
3387f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3388f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD50           = 50,  /**< Interim AOT for Rsvd50                   */
3389f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE;
3390f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3391ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
3392ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        const void *esds_data, size_t esds_size) {
3393ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    ESDS esds(esds_data, esds_size);
339481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
339581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    uint8_t objectTypeIndication;
339681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
339781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return ERROR_MALFORMED;
339881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
339981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
340081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (objectTypeIndication == 0xe1) {
340181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // This isn't MPEG4 audio at all, it's QCELP 14k...
3402f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        if (mLastTrack == NULL)
3403f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            return ERROR_MALFORMED;
3404f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
340581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
340681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return OK;
340781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
340881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
3409633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong    if (objectTypeIndication  == 0x6b) {
3410633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // The media subtype is MP3 audio
3411633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // Our software MP3 audio decoder may not be able to handle
3412633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
341329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("MP3 track in MP4/3GPP file is not supported");
3414633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        return ERROR_UNSUPPORTED;
3415633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong    }
3416633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong
3417ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    const uint8_t *csd;
3418ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    size_t csd_size;
3419ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (esds.getCodecSpecificInfo(
3420ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                (const void **)&csd, &csd_size) != OK) {
3421ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
3422ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3423ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3424b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    if (kUseHexDump) {
3425ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        printf("ESD of size %zu\n", csd_size);
3426b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        hexdump(csd, csd_size);
3427b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    }
3428ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3429a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    if (csd_size == 0) {
3430a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // There's no further information, i.e. no codec specific data
3431a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // Let's assume that the information provided in the mpeg4 headers
3432a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // is accurate and hope for the best.
3433a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
3434a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        return OK;
3435a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    }
3436a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
3437ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (csd_size < 2) {
3438ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
3439ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3440ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
344100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    static uint32_t kSamplingRate[] = {
344200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
344300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        16000, 12000, 11025, 8000, 7350
344400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    };
344500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent
3446aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    ABitReader br(csd, csd_size);
3447aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    uint32_t objectType = br.getBits(5);
3448ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3449aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (objectType == 31) {  // AAC-ELD => additional 6 bits
3450aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        objectType = 32 + br.getBits(6);
3451ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3452ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3453f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
3454f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
3455f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
3456db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    //keep AOT type
3457db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
3458db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
3459aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    uint32_t freqIndex = br.getBits(4);
3460aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
3461ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t sampleRate = 0;
3462ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t numChannels = 0;
3463ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (freqIndex == 15) {
34648e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
3465aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        sampleRate = br.getBits(24);
3466aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        numChannels = br.getBits(4);
3467ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    } else {
34688e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3469595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen        numChannels = br.getBits(4);
347000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent
347100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        if (freqIndex == 13 || freqIndex == 14) {
347200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            return ERROR_MALFORMED;
3473ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        }
3474ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
347500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        sampleRate = kSamplingRate[freqIndex];
347600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    }
3477595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen
3478f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
34798e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
348000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        uint32_t extFreqIndex = br.getBits(4);
3481b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        int32_t extSampleRate __unused;
348200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        if (extFreqIndex == 15) {
348300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            if (csd_size < 8) {
3484595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen                return ERROR_MALFORMED;
3485595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen            }
34868e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
348700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            extSampleRate = br.getBits(24);
348800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        } else {
348900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            if (extFreqIndex == 13 || extFreqIndex == 14) {
349000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent                return ERROR_MALFORMED;
349100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            }
349200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            extSampleRate = kSamplingRate[extFreqIndex];
3493595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen        }
349400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        //TODO: save the extension sampling rate value in meta data =>
349500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        //      mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
3496ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3497ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3498f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    switch (numChannels) {
3499f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
3500f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 0:
3501f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 1:// FC
3502f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 2:// FL FR
3503f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 3:// FC, FL FR
3504f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 4:// FC, FL FR, RC
3505f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 5:// FC, FL FR, SL SR
3506f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 6:// FC, FL FR, SL SR, LFE
3507f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            //numChannels already contains the right value
3508f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3509f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 11:// FC, FL FR, SL SR, RC, LFE
3510f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            numChannels = 7;
3511f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3512f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 7: // FC, FCL FCR, FL FR, SL SR, LFE
3513f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 12:// FC, FL  FR,  SL SR, RL RR, LFE
3514f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 14:// FC, FL  FR,  SL SR, LFE, FHL FHR
3515f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            numChannels = 8;
3516f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3517f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        default:
3518f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            return ERROR_UNSUPPORTED;
3519f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    }
3520f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3521f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    {
3522f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        if (objectType == AOT_SBR || objectType == AOT_PS) {
35238e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3524f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            objectType = br.getBits(5);
3525f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3526f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            if (objectType == AOT_ESCAPE) {
35278e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
3528f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType = 32 + br.getBits(6);
3529f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3530f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        }
3531f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
3532f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
3533f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType == AOT_ER_BSAC) {
35348e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
3535b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            const int32_t frameLengthFlag __unused = br.getBits(1);
3536f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3537f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            const int32_t dependsOnCoreCoder = br.getBits(1);
3538f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3539f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            if (dependsOnCoreCoder ) {
35408e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
3541b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t coreCoderDelay __unused = br.getBits(14);
3542f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3543f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
354445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            int32_t extensionFlag = -1;
354545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            if (br.numBitsLeft() > 0) {
354645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                extensionFlag = br.getBits(1);
354745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            } else {
354845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                switch (objectType) {
354945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                // 14496-3 4.5.1.1 extensionFlag
355045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_AAC_LC:
355145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    extensionFlag = 0;
355245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
355345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_LC:
355445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_SCAL:
355545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_BSAC:
355645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_LD:
355745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    extensionFlag = 1;
355845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
355945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                default:
35608e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    return ERROR_MALFORMED;
356145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
356245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                }
356345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                ALOGW("csd missing extension flag; assuming %d for object type %u.",
356445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                        extensionFlag, objectType);
356545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            }
3566f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
356745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            if (numChannels == 0) {
3568f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int32_t channelsEffectiveNum = 0;
3569f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int32_t channelsNum = 0;
35708e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 32) {
35718e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    return ERROR_MALFORMED;
35728e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                }
3573b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t ElementInstanceTag __unused = br.getBits(4);
3574b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t Profile __unused = br.getBits(2);
3575b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
3576f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumFrontChannelElements = br.getBits(4);
3577f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumSideChannelElements = br.getBits(4);
3578f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumBackChannelElements = br.getBits(4);
3579f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumLfeChannelElements = br.getBits(2);
3580b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t NumAssocDataElements __unused = br.getBits(3);
3581b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t NumValidCcElements __unused = br.getBits(4);
3582f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3583f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t MonoMixdownPresent = br.getBits(1);
35848e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen
3585f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (MonoMixdownPresent != 0) {
35868e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3587b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
3588f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3589f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
35908e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3591f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t StereoMixdownPresent = br.getBits(1);
3592f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (StereoMixdownPresent != 0) {
35938e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3594b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
3595f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3596f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
35978e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3598f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t MatrixMixdownIndexPresent = br.getBits(1);
3599f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (MatrixMixdownIndexPresent != 0) {
36008e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
3601b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t MatrixMixdownIndex __unused = br.getBits(2);
3602b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t PseudoSurroundEnable __unused = br.getBits(1);
3603f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3604f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3605f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int i;
3606f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumFrontChannelElements; i++) {
36078e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3608f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t FrontElementIsCpe = br.getBits(1);
3609b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t FrontElementTagSelect __unused = br.getBits(4);
3610f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += FrontElementIsCpe ? 2 : 1;
3611f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3612f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3613f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumSideChannelElements; i++) {
36148e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3615f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t SideElementIsCpe = br.getBits(1);
3616b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t SideElementTagSelect __unused = br.getBits(4);
3617f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += SideElementIsCpe ? 2 : 1;
3618f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3619f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3620f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumBackChannelElements; i++) {
36218e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3622f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t BackElementIsCpe = br.getBits(1);
3623b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t BackElementTagSelect __unused = br.getBits(4);
3624f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += BackElementIsCpe ? 2 : 1;
3625f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3626f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                channelsEffectiveNum = channelsNum;
3627f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3628f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumLfeChannelElements; i++) {
36298e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3630b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t LfeElementTagSelect __unused = br.getBits(4);
3631f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += 1;
3632f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3633f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
3634f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
3635f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                numChannels = channelsNum;
3636f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3637f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        }
3638f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    }
3639f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3640ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (numChannels == 0) {
3641ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_UNSUPPORTED;
3642ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3643ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3644f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
3645f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
3646f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
3647ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevSampleRate;
3648ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
3649ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3650ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevSampleRate != sampleRate) {
36513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("mpeg4 audio sample rate different from previous setting. "
3652ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevSampleRate, sampleRate);
3653ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3654ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3655ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
3656ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3657ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevChannelCount;
3658ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
3659ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3660ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevChannelCount != numChannels) {
36613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("mpeg4 audio channel count different from previous setting. "
3662ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevChannelCount, numChannels);
3663ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3664ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3665ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
3666ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3667ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    return OK;
3668ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber}
3669ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
367020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
367120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
367220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source(
3673942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen        const sp<MPEG4Extractor> &owner,
367420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const sp<MetaData> &format,
3675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &dataSource,
367648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        int32_t timeScale,
367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const sp<SampleTable> &sampleTable,
367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        Vector<SidxEntry> &sidx,
3679c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        const Trex *trex,
368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t firstMoofOffset)
3681942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    : mOwner(owner),
3682942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen      mFormat(format),
368320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDataSource(dataSource),
368448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber      mTimescale(timeScale),
368520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleTable(sampleTable),
368620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mCurrentSampleIndex(0),
368705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentFragmentIndex(0),
368805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mSegments(sidx),
3689c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen      mTrex(trex),
369005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mFirstMoofOffset(firstMoofOffset),
369105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentMoofOffset(firstMoofOffset),
3692ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia      mNextMoofOffset(-1),
369305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentTime(0),
3694ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoAllocSize(0),
3695ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoSizes(NULL),
3696ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoOffsetsAllocSize(0),
3697ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoOffsets(NULL),
369820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mIsAVC(false),
36993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar      mIsHEVC(false),
37006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber      mNALLengthSize(0),
370120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStarted(false),
370220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mGroup(NULL),
370320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mBuffer(NULL),
3704dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber      mWantsNALFragments(false),
37050024245e134467d120b40099da16c467dc365e76Andreas Huber      mSrcBuffer(NULL) {
3706ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3707c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
3708c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3709ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
371048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    mDefaultIVSize = 0;
3711ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
3712ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t keytype;
3713ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    const void *key;
3714ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    size_t keysize;
3715ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
3716ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        CHECK(keysize <= 16);
3717ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memset(mCryptoKey, 0, 16);
3718ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memcpy(mCryptoKey, key, keysize);
3719ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3720ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
372120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
372220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = mFormat->findCString(kKeyMIMEType, &mime);
3723dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(success);
372420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
372518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
37263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
37276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    if (mIsAVC) {
37296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        uint32_t type;
37306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const void *data;
37316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t size;
37326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
37336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const uint8_t *ptr = (const uint8_t *)data;
37356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(size >= 7);
3737ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
37386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37396064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        // The number of bytes used to encode the length of a NAL unit.
37406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        mNALLengthSize = 1 + (ptr[4] & 3);
37413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (mIsHEVC) {
37423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        uint32_t type;
37433b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const void *data;
37443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t size;
37453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        CHECK(format->findData(kKeyHVCC, &type, &data, &size));
37463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
37473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
37483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3749a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        CHECK(size >= 22);
37503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
37513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
37523b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        mNALLengthSize = 1 + (ptr[14 + 7] & 3);
37536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
375405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
375505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    CHECK(format->findInt32(kKeyTrackID, &mTrackId));
375605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
3757ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia}
3758ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia
3759ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jiastatus_t MPEG4Source::init() {
376005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mFirstMoofOffset != 0) {
376105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t offset = mFirstMoofOffset;
3762ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia        return parseChunk(&offset);
376305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
3764ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    return OK;
376520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
376620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
376720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() {
376820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
376920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        stop();
377020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
3771ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    free(mCurrentSampleInfoSizes);
3772ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    free(mCurrentSampleInfoOffsets);
377320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
377420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
377520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) {
37767b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
37777b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
3778dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(!mStarted);
377920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
378020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t val;
3781dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (params && params->findInt32(kKeyWantsNALFragments, &val)
378220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        && val != 0) {
3783dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = true;
378420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
3785dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = false;
378620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
378720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3788afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    int32_t tmp;
3789afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp));
3790afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    size_t max_size = tmp;
379120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3792afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    // A somewhat arbitrary limit that should be sufficient for 8k video frames
3793afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    // If you see the message below for a valid input stream: increase the limit
3794cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    const size_t kMaxBufferSize = 64 * 1024 * 1024;
3795cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (max_size > kMaxBufferSize) {
3796cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize);
3797cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        return ERROR_MALFORMED;
3798cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
3799cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (max_size == 0) {
3800cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        ALOGE("zero max input size");
3801afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        return ERROR_MALFORMED;
3802afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    }
38030024245e134467d120b40099da16c467dc365e76Andreas Huber
3804cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize.
3805cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    const size_t kMaxBuffers = 8;
3806cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers);
3807cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    mGroup = new MediaBufferGroup(buffers, max_size);
38088da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    mSrcBuffer = new (std::nothrow) uint8_t[max_size];
38098da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (mSrcBuffer == NULL) {
38108da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        // file probably specified a bad max size
3811afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        delete mGroup;
3812afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        mGroup = NULL;
38138da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
38148da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
381520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
381620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = true;
381720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
381820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
381920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
382020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
382120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() {
38227b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
38237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
3824dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
382520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
382620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mBuffer != NULL) {
382720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->release();
382820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
382920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
383020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38310024245e134467d120b40099da16c467dc365e76Andreas Huber    delete[] mSrcBuffer;
38320024245e134467d120b40099da16c467dc365e76Andreas Huber    mSrcBuffer = NULL;
38330024245e134467d120b40099da16c467dc365e76Andreas Huber
383420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete mGroup;
383520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mGroup = NULL;
383620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
383720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = false;
383820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCurrentSampleIndex = 0;
383920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
384020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
384120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
384220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
384305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) {
384405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t hdr[2];
384505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
384605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_IO;
384705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
384805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t chunk_size = ntohl(hdr[0]);
384905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t chunk_type = ntohl(hdr[1]);
385005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t data_offset = *offset + 8;
385105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
385205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (chunk_size == 1) {
385305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
385405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_IO;
385505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
385605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        chunk_size = ntoh64(chunk_size);
385705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        data_offset += 8;
385805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
385905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (chunk_size < 16) {
386005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            // The smallest valid chunk is 16 bytes long in this case.
386105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
386205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
386305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (chunk_size < 8) {
386405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // The smallest valid chunk is 8 bytes long.
386505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
386605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
386705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
386805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    char chunk[5];
386905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    MakeFourCCString(chunk_type, chunk);
3870ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
387105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
387205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t chunk_data_size = *offset + chunk_size - data_offset;
387305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
387405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    switch(chunk_type) {
387505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
387605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'r', 'a', 'f'):
387705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('m', 'o', 'o', 'f'): {
387805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            off64_t stop_offset = *offset + chunk_size;
387905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset = data_offset;
388005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            while (*offset < stop_offset) {
388105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err = parseChunk(offset);
388205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (err != OK) {
388305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return err;
388405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
388505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
388605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
38873f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                // *offset points to the box following this moof. Find the next moof from there.
38883f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen
38893f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                while (true) {
38903f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
38913f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        return ERROR_END_OF_STREAM;
38923f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    }
38933f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    chunk_size = ntohl(hdr[0]);
38943f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    chunk_type = ntohl(hdr[1]);
3895ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    if (chunk_size == 1) {
3896ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box
3897ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // which is defined in 4.2 Object Structure.
3898ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // When chunk_size==1, 8 bytes follows as "largesize".
3899ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
3900ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                            return ERROR_IO;
3901ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        }
3902ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        chunk_size = ntoh64(chunk_size);
3903ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        if (chunk_size < 16) {
3904ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                            // The smallest valid chunk is 16 bytes long in this case.
3905ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                            return ERROR_MALFORMED;
3906ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        }
3907ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    } else if (chunk_size == 0) {
3908ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // next box extends to end of file.
3909ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    } else if (chunk_size < 8) {
3910ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // The smallest valid chunk is 8 bytes long in this case.
3911ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        return ERROR_MALFORMED;
3912ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    }
3913ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia
39143f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
39153f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        mNextMoofOffset = *offset;
39163f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        break;
3917ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    } else if (chunk_size == 0) {
3918ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        break;
39193f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    }
39203f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    *offset += chunk_size;
39213f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                }
392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            break;
392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
392505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
392605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'f', 'h', 'd'): {
392705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err;
392805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
392905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return err;
393005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
393105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                *offset += chunk_size;
393205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                break;
393305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
393405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
393505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'r', 'u', 'n'): {
393605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err;
393705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (mLastParsedTrackId == mTrackId) {
393805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
393905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        return err;
394005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    }
394105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
394205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                *offset += chunk_size;
394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                break;
394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
3947ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'a', 'i', 'z'): {
3948ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            status_t err;
3949ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
3950ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return err;
3951ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3952ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3953ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3954ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3955ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'a', 'i', 'o'): {
3956ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            status_t err;
3957ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
3958ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return err;
3959ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3960ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3961ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3962ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3963ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3964ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('m', 'd', 'a', 't'): {
3965ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // parse DRM info if present
3966ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("MPEG4Source::parseChunk mdat");
3967ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // if saiz/saoi was previously observed, do something with the sampleinfos
3968ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3969ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3970ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3971ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        default: {
397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset += chunk_size;
397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            break;
397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
398084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
398184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t offset, off64_t /* size */) {
3982ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    ALOGV("parseSampleAuxiliaryInformationSizes");
3983ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // 14496-12 8.7.12
3984ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t version;
3985ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(
3986ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset, &version, sizeof(version))
3987ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            < (ssize_t)sizeof(version)) {
3988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3989ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3990ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3991ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (version != 0) {
3992ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_UNSUPPORTED;
3993ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3994ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
3995ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3996ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t flags;
3997ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt24(offset, &flags)) {
3998ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
3999ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4000ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 3;
4001ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4002ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (flags & 1) {
4003ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        uint32_t tmp;
4004ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
4005ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_MALFORMED;
4006ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4007ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentAuxInfoType = tmp;
4008ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        offset += 4;
4009ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
4010ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_MALFORMED;
4011ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4012ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentAuxInfoTypeParameter = tmp;
4013ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        offset += 4;
4014ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4015ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4016ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t defsize;
4017ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(offset, &defsize, 1) != 1) {
4018ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_MALFORMED;
4019ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4020ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mCurrentDefaultSampleInfoSize = defsize;
4021ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
4022ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4023ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t smplcnt;
4024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &smplcnt)) {
4025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_MALFORMED;
4026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
402748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    mCurrentSampleInfoCount = smplcnt;
4028ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 4;
4029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
403048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (mCurrentDefaultSampleInfoSize != 0) {
403148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
403248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return OK;
403348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
4034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (smplcnt > mCurrentSampleInfoAllocSize) {
4035b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        uint8_t * newPtr =  (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
4036b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        if (newPtr == NULL) {
4037b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoAllocSize, smplcnt);
4038b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen            return NO_MEMORY;
4039b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        }
4040b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        mCurrentSampleInfoSizes = newPtr;
4041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoAllocSize = smplcnt;
4042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
4045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
4046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
4047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
404884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
404984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t offset, off64_t /* size */) {
4050ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    ALOGV("parseSampleAuxiliaryInformationOffsets");
4051ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // 14496-12 8.7.13
4052ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t version;
4053ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
4054ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
4057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t flags;
4059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt24(offset, &flags)) {
4060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 3;
4063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t entrycount;
4065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &entrycount)) {
4066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 4;
4069c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (entrycount == 0) {
4070c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return OK;
4071c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
4072c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (entrycount > UINT32_MAX / 8) {
4073c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return ERROR_MALFORMED;
4074c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
4075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
4077c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
4078c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        if (newPtr == NULL) {
4079b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
4080c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia            return NO_MEMORY;
4081c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        }
4082c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        mCurrentSampleInfoOffsets = newPtr;
4083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoOffsetsAllocSize = entrycount;
4084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mCurrentSampleInfoOffsetCount = entrycount;
4086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4087c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (mCurrentSampleInfoOffsets == NULL) {
4088c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return OK;
4089c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
4090c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia
4091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < entrycount; i++) {
4092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (version == 0) {
4093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t tmp;
4094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (!mDataSource->getUInt32(offset, &tmp)) {
4095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
4096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
4097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mCurrentSampleInfoOffsets[i] = tmp;
4098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset += 4;
4099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        } else {
4100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint64_t tmp;
4101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (!mDataSource->getUInt64(offset, &tmp)) {
4102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
4103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
4104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mCurrentSampleInfoOffsets[i] = tmp;
4105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset += 8;
4106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // parse clear/encrypted data
4110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
4112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    drmoffset += mCurrentMoofOffset;
4114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int ivlength;
4115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
411648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
4117529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    // only 0, 8 and 16 byte initialization vectors are supported
4118529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
4119529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        ALOGW("unsupported IV length: %d", ivlength);
4120529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        return ERROR_MALFORMED;
4121529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    }
412248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    // read CencSampleAuxiliaryDataFormats
4123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
4124529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        if (i >= mCurrentSamples.size()) {
4125529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen            ALOGW("too few samples");
4126529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen            break;
4127529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        }
4128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Sample *smpl = &mCurrentSamples.editItemAt(i);
4129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memset(smpl->iv, 0, 16);
4131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) {
4132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_IO;
4133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        drmoffset += ivlength;
4136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
413748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
413848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        if (smplinfosize == 0) {
413948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smplinfosize = mCurrentSampleInfoSizes[i];
4140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
414148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        if (smplinfosize > ivlength) {
414248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint16_t numsubsamples;
414348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
4144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
4145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
4146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            drmoffset += 2;
414748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            for (size_t j = 0; j < numsubsamples; j++) {
414848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                uint16_t numclear;
414948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                uint32_t numencrypted;
415048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                if (!mDataSource->getUInt16(drmoffset, &numclear)) {
415148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                    return ERROR_IO;
415248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                }
415348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                drmoffset += 2;
415448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
415548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                    return ERROR_IO;
415648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                }
415748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                drmoffset += 4;
415848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->clearsizes.add(numclear);
415948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->encryptedsizes.add(numencrypted);
4160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
416148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        } else {
416248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smpl->clearsizes.add(0);
416348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smpl->encryptedsizes.add(smpl->size);
4164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4166ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
4169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
4170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
417105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
417205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
417305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 8) {
417405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
417505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
417605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
417705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
4178ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
417905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
418005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
418105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
418205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & 0xff000000) {
418305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
418405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
418505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
418605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
418705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
418805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
418905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
419005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mLastParsedTrackId != mTrackId) {
419105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // this is not the right track, skip it
419205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
419305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
419405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
419505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mFlags = flags;
419605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
419705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 8;
419805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 8;
419905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
420005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
420105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
420205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
420305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 8) {
420405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
420505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
420605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
420705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
420805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
420905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
421005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 8;
421105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 8;
421205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
421305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
421405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
421505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
421605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
421705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
421805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
421905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
422005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
422105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
422205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
422305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
422405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
422505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
422605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
422705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
422805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
422905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
423005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
423105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
423205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
423305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
423405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
423505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
423605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
423705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
423805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
423905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
424005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
424105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
424205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
424305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
424405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
424505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
424605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
424705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
424805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
424905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
425005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
425105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
425205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
425305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
425405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
425505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
425605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
425705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
425805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
425905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
426005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
426105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
426205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
426305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
426405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
426505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
426605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mDataOffset = 0;
426705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
426805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
426905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
427005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
427105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
427205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("MPEG4Extractor::parseTrackFragmentRun");
427305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 8) {
427405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
427505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
427605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
427705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    enum {
427805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kDataOffsetPresent                  = 0x01,
427905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kFirstSampleFlagsPresent            = 0x04,
428005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleDurationPresent              = 0x100,
428105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleSizePresent                  = 0x200,
428205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleFlagsPresent                 = 0x400,
428305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleCompositionTimeOffsetPresent = 0x800,
428405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
428505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
428605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
428705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) {
428805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
428905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
429044a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // |version| only affects SampleCompositionTimeOffset field.
429144a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // If version == 0, SampleCompositionTimeOffset is uint32_t;
429244a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // Otherwise, SampleCompositionTimeOffset is int32_t.
429344a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // Sample.compositionOffset is defined as int32_t.
429444a9bf5b013641a55d1784da353461e7446ff756Wei Jia    uint8_t version = flags >> 24;
429544a9bf5b013641a55d1784da353461e7446ff756Wei Jia    flags &= 0xffffff;
429644a9bf5b013641a55d1784da353461e7446ff756Wei Jia    ALOGV("fragment run version: 0x%02x, flags: 0x%06x", version, flags);
429705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
429805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
429905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // These two shall not be used together.
430005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
430105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
430205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
430305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t sampleCount;
430405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
430505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
430605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
430705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 8;
430805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 8;
430905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
431005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
431105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
431205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t firstSampleFlags = 0;
431305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
431405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kDataOffsetPresent) {
431505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
431605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
431705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
431805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
431905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int32_t dataOffsetDelta;
432005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) {
432105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
432205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
432305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
432405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
432505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
432605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
432705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
432805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
432905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
433005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kFirstSampleFlagsPresent) {
433105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
433205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
433305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
433405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
433505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
433605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
433705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
433805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
433905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
434005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
434105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
434205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
434305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen             sampleCtsOffset = 0;
434405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
434505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size_t bytesPerSample = 0;
434605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleDurationPresent) {
434705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
434805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
434905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
435005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
4351c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    } else if (mTrex) {
4352c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        sampleDuration = mTrex->default_sample_duration;
435305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
435405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
435505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleSizePresent) {
435605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
435705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
435805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
435905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
436005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
436105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
436205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
436305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
436405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleFlagsPresent) {
436505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
436605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
436705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
436805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
436905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
437005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
437105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
437205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
437305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleCompositionTimeOffsetPresent) {
437405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
437505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
437605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleCtsOffset = 0;
437705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
437805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4379ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (size < (off64_t)(sampleCount * bytesPerSample)) {
438005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
438105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
438205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
438305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Sample tmp;
438405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    for (uint32_t i = 0; i < sampleCount; ++i) {
438505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleDurationPresent) {
438605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleDuration)) {
438705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
438805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
438905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
439005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
439105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
439205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleSizePresent) {
439305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleSize)) {
439405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
439505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
439605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
439705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
439805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
439905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleFlagsPresent) {
440005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleFlags)) {
440105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
440205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
440305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
440405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
440505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
440605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleCompositionTimeOffsetPresent) {
440705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
440805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
440905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
441005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
441105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
441205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4413a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
4414ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen              " flags 0x%08x", i + 1,
441505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dataOffset, sampleSize, sampleDuration,
441605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                (flags & kFirstSampleFlagsPresent) && i == 0
441705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    ? firstSampleFlags : sampleFlags);
441805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.offset = dataOffset;
441905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.size = sampleSize;
442005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.duration = sampleDuration;
4421c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        tmp.compositionOffset = sampleCtsOffset;
442205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mCurrentSamples.add(tmp);
442305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
442405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        dataOffset += sampleSize;
442505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
442605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
442705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
442805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
442905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
443005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
443105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
443220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() {
44337b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
44347b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
443520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mFormat;
443620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
443720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const {
44396064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    switch (mNALLengthSize) {
44406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 1:
44416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return *data;
44426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 2:
44436064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U16_AT(data);
44446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 3:
44456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
44466064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 4:
44476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U32_AT(data);
44486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
44496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
44506064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // This cannot happen, mNALLengthSize springs to life by adding 1 to
44516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // a 2-bit integer.
44526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    CHECK(!"Should not be here.");
44536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
44546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    return 0;
44556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber}
44566064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
445720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read(
445820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
44597b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
44607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
4461dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
446220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4463cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
4464cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        *out = nullptr;
4465cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        return WOULD_BLOCK;
4466cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
4467cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
446805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mFirstMoofOffset > 0) {
446905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return fragmentedRead(out, options);
447005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
447105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
447220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *out = NULL;
447320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4474abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    int64_t targetSampleTimeUs = -1;
4475abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
447620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int64_t seekTimeUs;
4477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
4478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4479abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t findFlags = 0;
4480abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        switch (mode) {
4481abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_PREVIOUS_SYNC:
4482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagBefore;
4483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_NEXT_SYNC:
4485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagAfter;
4486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST_SYNC:
4488abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST:
4489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagClosest;
4490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            default:
4492abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(!"Should not be here.");
4493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
449620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t sampleIndex;
4497abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleTable->findSampleAtTime(
4498599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                seekTimeUs, 1000000, mTimescale,
4499abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                &sampleIndex, findFlags);
4500abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4501abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
4502abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // We found the closest sample already, now we want the sync
4503abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // sample preceding it (or the sample itself of course), even
4504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // if the subsequent sync sample is closer.
4505abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            findFlags = SampleTable::kFlagBefore;
4506abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4507abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4508abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleIndex;
4509abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err == OK) {
4510abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            err = mSampleTable->findSyncSampleNear(
4511abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    sampleIndex, &syncSampleIndex, findFlags);
4512abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
451320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4514788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        uint32_t sampleTime;
4515788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        if (err == OK) {
4516788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber            err = mSampleTable->getMetaDataForSample(
4517788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber                    sampleIndex, NULL, NULL, &sampleTime);
4518788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        }
4519788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber
452020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
45215295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            if (err == ERROR_OUT_OF_RANGE) {
45225295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // An attempt to seek past the end of the stream would
45235295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
45245295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // this all the way to the MediaPlayer would cause abnormal
45255295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // termination. Legacy behaviour appears to be to behave as if
45265295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // we had seeked to the end of stream, ending normally.
45275295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                err = ERROR_END_OF_STREAM;
45285295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            }
452905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGV("end of stream");
453020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
453120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
453220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
4534abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
4535abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4536abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4537abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0
4538abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleTime;
4539abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
4540abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    syncSampleIndex, NULL, NULL, &syncSampleTime));
4541abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4542df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("seek to time %lld us => sample at time %lld us, "
4543abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             "sync sample at time %lld us",
4544abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             seekTimeUs,
4545abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             sampleTime * 1000000ll / mTimescale,
4546abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             syncSampleTime * 1000000ll / mTimescale);
4547abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif
4548abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4549abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        mCurrentSampleIndex = syncSampleIndex;
455020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mBuffer != NULL) {
455120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
455220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
455320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
455420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
455520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // fall through
455620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
455720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4558c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset;
45590024245e134467d120b40099da16c467dc365e76Andreas Huber    size_t size;
4560170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    uint32_t cts, stts;
45618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    bool isSyncSample;
4562dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool newBuffer = false;
4563dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mBuffer == NULL) {
4564dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        newBuffer = true;
456520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4566c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err =
4567c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mSampleTable->getMetaDataForSample(
4568170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
456920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4570dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
4571dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
4572dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4573dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4574dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        err = mGroup->acquire_buffer(&mBuffer);
4575c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
4576dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
4577ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            CHECK(mBuffer == NULL);
4578dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
4579dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4580c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        if (size > mBuffer->size()) {
4581c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4582c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            return ERROR_BUFFER_TOO_SMALL;
4583c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        }
45840024245e134467d120b40099da16c467dc365e76Andreas Huber    }
458520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
4587dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (newBuffer) {
4588dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ssize_t num_bytes_read =
458934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4590dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4591dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            if (num_bytes_read < (ssize_t)size) {
4592dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer->release();
4593dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer = NULL;
4594dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4595dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                return ERROR_IO;
4596dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            }
4597dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
45987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber            CHECK(mBuffer != NULL);
4599dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->set_range(0, size);
4600dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->meta_data()->clear();
460148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            mBuffer->meta_data()->setInt64(
46024678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4603170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            mBuffer->meta_data()->setInt64(
4604170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4605abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4606abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (targetSampleTimeUs >= 0) {
4607abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                mBuffer->meta_data()->setInt64(
4608abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                        kKeyTargetTime, targetSampleTimeUs);
4609abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
4610abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
46118bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (isSyncSample) {
46128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
46138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
46148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4615dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ++mCurrentSampleIndex;
4616dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4617dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!mIsAVC && !mIsHEVC) {
4619dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            *out = mBuffer;
4620dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
4621dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4622dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return OK;
4623dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4624dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4625dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Each NAL unit is split up into its constituent fragments and
4626dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // each one of them returned in its own buffer.
4627dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize);
4629dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4630dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        const uint8_t *src =
4631dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
4632dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t nal_size = parseNALSize(src);
46345d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mNALLengthSize > SIZE_MAX - nal_size) {
46355d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen            ALOGE("b/24441553, b/24445122");
46365d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        }
46375d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
463829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("incomplete NAL unit.");
4639e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4640e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer->release();
4641e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer = NULL;
4642e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4643e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            return ERROR_MALFORMED;
4644e8a084958c27327b0aca749f69095605d2a21309Andreas Huber        }
4645dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4646dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        MediaBuffer *clone = mBuffer->clone();
46477b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(clone != NULL);
46486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
4649dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46507b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(mBuffer != NULL);
4651dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mBuffer->set_range(
46526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_offset() + mNALLengthSize + nal_size,
46536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_length() - mNALLengthSize - nal_size);
4654dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4655dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (mBuffer->range_length() == 0) {
4656dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->release();
4657dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
4658dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4659dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4660dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        *out = clone;
4661dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4662dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        return OK;
4663dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    } else {
4664dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Whole NAL units are returned but each fragment is prefixed by
4665dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // the start code (0x00 00 00 01).
4666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        ssize_t num_bytes_read = 0;
4667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t drm = 0;
4668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
4669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
4670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read =
4671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
4672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
4673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
4674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
467520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
467620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (num_bytes_read < (ssize_t)size) {
467720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
467820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
467920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4680dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return ERROR_IO;
468120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
468220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
4684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
4685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, size);
46866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
4687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
4688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t *dstData = (uint8_t *)mBuffer->data();
4689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t srcOffset = 0;
4690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t dstOffset = 0;
4691e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (srcOffset < size) {
4693bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
469434fe252c89e33572d01fea981b58d7b115e76164James Dong                size_t nalLength = 0;
469534fe252c89e33572d01fea981b58d7b115e76164James Dong                if (!isMalFormed) {
469634fe252c89e33572d01fea981b58d7b115e76164James Dong                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
469734fe252c89e33572d01fea981b58d7b115e76164James Dong                    srcOffset += mNALLengthSize;
4698bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
469934fe252c89e33572d01fea981b58d7b115e76164James Dong                }
4700e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
470134fe252c89e33572d01fea981b58d7b115e76164James Dong                if (isMalFormed) {
470229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Video is malformed");
4703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer->release();
4704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer = NULL;
4705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return ERROR_MALFORMED;
4706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
4707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
4708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (nalLength == 0) {
4709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    continue;
4710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
4711dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
471287afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                if (dstOffset > SIZE_MAX - 4 ||
471387afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                        dstOffset + 4 > SIZE_MAX - nalLength ||
471487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                        dstOffset + 4 + nalLength > mBuffer->size()) {
471587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
471687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    android_errorWriteLog(0x534e4554, "27208621");
471787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    mBuffer->release();
471887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    mBuffer = NULL;
471987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    return ERROR_MALFORMED;
472087afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                }
4721dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4725dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 1;
4726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
4727dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                srcOffset += nalLength;
4728dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstOffset += nalLength;
4729dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
4730dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK_EQ(srcOffset, size);
4731dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
4732dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, dstOffset);
4733dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4734dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
473520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->meta_data()->clear();
473648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        mBuffer->meta_data()->setInt64(
47374678a6dc5f09008481524949a9667af5a6190374Andreas Huber                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4738170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        mBuffer->meta_data()->setInt64(
4739170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4741abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (targetSampleTimeUs >= 0) {
4742abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            mBuffer->meta_data()->setInt64(
4743abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    kKeyTargetTime, targetSampleTimeUs);
4744abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4745abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
47464dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        if (mIsAVC) {
47474dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            uint32_t layerId = FindAVCLayerId(
47484dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
47494dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
47504dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        }
47514dbff11975e737482537e1636051690188f3fbc4Praveen Chavan
47528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (isSyncSample) {
47538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
47548bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
47558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
475620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        ++mCurrentSampleIndex;
475720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
475820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *out = mBuffer;
475920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
476020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
476120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
476220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
476320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
476420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
476505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead(
476605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MediaBuffer **out, const ReadOptions *options) {
476705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
476805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("MPEG4Source::fragmentedRead");
476905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
477005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    CHECK(mStarted);
477105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
477205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *out = NULL;
477305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
477405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t targetSampleTimeUs = -1;
477505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
477605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t seekTimeUs;
477705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ReadOptions::SeekMode mode;
477805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
477905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
478005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int numSidxEntries = mSegments.size();
478105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (numSidxEntries != 0) {
478205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            int64_t totalTime = 0;
478305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            off64_t totalOffset = mFirstMoofOffset;
478405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            for (int i = 0; i < numSidxEntries; i++) {
478505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                const SidxEntry *se = &mSegments[i];
478605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (totalTime + se->mDurationUs > seekTimeUs) {
478705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    // The requested time is somewhere in this segment
47883f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) ||
478905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
479005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
479105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        // requested next sync, or closest sync and it was closer to the end of
479205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        // this segment
479305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        totalTime += se->mDurationUs;
479405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        totalOffset += se->mSize;
479505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    }
479605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    break;
479705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
479805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                totalTime += se->mDurationUs;
479905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                totalOffset += se->mSize;
480005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
4801ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentMoofOffset = totalOffset;
4802ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            mNextMoofOffset = -1;
4803ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSamples.clear();
4804ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSampleIndex = 0;
4805ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseChunk(&totalOffset);
4806ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
4807ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
4808ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
4809ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentTime = totalTime * mTimescale / 1000000ll;
4810ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen        } else {
4811ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            // without sidx boxes, we can only seek to 0
4812ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentMoofOffset = mFirstMoofOffset;
4813ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            mNextMoofOffset = -1;
4814ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSamples.clear();
4815ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSampleIndex = 0;
4816ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            off64_t tmp = mCurrentMoofOffset;
4817ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseChunk(&tmp);
4818ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
4819ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
4820ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
4821ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentTime = 0;
482205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
482305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
482405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mBuffer != NULL) {
482505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
482605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
482705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
482805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
482905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // fall through
483005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
483105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
483205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t offset = 0;
4833442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber    size_t size = 0;
483405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t cts = 0;
483505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    bool isSyncSample = false;
483605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    bool newBuffer = false;
483705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mBuffer == NULL) {
483805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        newBuffer = true;
483905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
484005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mCurrentSampleIndex >= mCurrentSamples.size()) {
48413f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            // move to next fragment if there is one
48423f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            if (mNextMoofOffset <= mCurrentMoofOffset) {
48433f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                return ERROR_END_OF_STREAM;
48443f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            }
4845ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            off64_t nextMoof = mNextMoofOffset;
484605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentMoofOffset = nextMoof;
484705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentSamples.clear();
484805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentSampleIndex = 0;
4849ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseChunk(&nextMoof);
4850ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
4851ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
4852ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
4853ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4854ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen                return ERROR_END_OF_STREAM;
4855ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            }
485605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
485705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
485805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
485905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset = smpl->offset;
486005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size = smpl->size;
4861c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        cts = mCurrentTime + smpl->compositionOffset;
486205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mCurrentTime += smpl->duration;
486305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        isSyncSample = (mCurrentSampleIndex == 0); // XXX
486405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
486505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        status_t err = mGroup->acquire_buffer(&mBuffer);
486605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
486705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (err != OK) {
486805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer == NULL);
486905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGV("acquire_buffer returned %d", err);
487005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return err;
487105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
4872c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        if (size > mBuffer->size()) {
4873c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4874c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            return ERROR_BUFFER_TOO_SMALL;
4875c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        }
487605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
487705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
487848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
487948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    const sp<MetaData> bufmeta = mBuffer->meta_data();
488048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    bufmeta->clear();
488148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (smpl->encryptedsizes.size()) {
488248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // store clear/encrypted lengths in metadata
488348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyPlainSizes, 0,
488448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
488548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyEncryptedSizes, 0,
488648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
488748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
488848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
488948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
489048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
489148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
489248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
48933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) {
489405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (newBuffer) {
4895da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (!isInRange((size_t)0u, mBuffer->size(), size)) {
4896da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer->release();
4897da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer = NULL;
4898da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
4899da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
4900da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                return ERROR_MALFORMED;
4901da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
4902da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
490305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ssize_t num_bytes_read =
490405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
490505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
490605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (num_bytes_read < (ssize_t)size) {
490705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->release();
490805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer = NULL;
490905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4910da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                ALOGE("i/o error");
491105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_IO;
491205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
491305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
491405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
491505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, size);
491605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt64(
491705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4918170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            mBuffer->meta_data()->setInt64(
4919170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
492005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
492105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (targetSampleTimeUs >= 0) {
492205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->meta_data()->setInt64(
492305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        kKeyTargetTime, targetSampleTimeUs);
492405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
492505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
49264dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            if (mIsAVC) {
49274dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                uint32_t layerId = FindAVCLayerId(
49284dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                        (const uint8_t *)mBuffer->data(), mBuffer->range_length());
49294dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
49304dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            }
49314dbff11975e737482537e1636051690188f3fbc4Praveen Chavan
493205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (isSyncSample) {
493305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
493405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
493505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
493605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ++mCurrentSampleIndex;
493705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
493805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
49393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!mIsAVC && !mIsHEVC) {
494005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *out = mBuffer;
494105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
494205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
494305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return OK;
494405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
494505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
494605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // Each NAL unit is split up into its constituent fragments and
494705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // each one of them returned in its own buffer.
494805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
494905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(mBuffer->range_length() >= mNALLengthSize);
495005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
495105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const uint8_t *src =
495205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
495305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
495405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size_t nal_size = parseNALSize(src);
49555d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mNALLengthSize > SIZE_MAX - nal_size) {
49565d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen            ALOGE("b/24441553, b/24445122");
49575d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        }
49585d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen
49595d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
496005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGE("incomplete NAL unit.");
496105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
496205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
496305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
496405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
496505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
496605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
496705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
496805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MediaBuffer *clone = mBuffer->clone();
496905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(clone != NULL);
497005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
497105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
497205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(mBuffer != NULL);
497305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer->set_range(
497405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->range_offset() + mNALLengthSize + nal_size,
497505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->range_length() - mNALLengthSize - nal_size);
497605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
497705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mBuffer->range_length() == 0) {
497805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
497905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
498005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
498105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
498205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        *out = clone;
498305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
498405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
498505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
498605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ALOGV("whole NAL");
498705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // Whole NAL units are returned but each fragment is prefixed by
498805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // the start code (0x00 00 00 01).
498905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ssize_t num_bytes_read = 0;
499005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int32_t drm = 0;
499105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
4992da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        void *data = NULL;
4993da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        bool isMalFormed = false;
499405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (usesDRM) {
4995da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
4996da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = true;
4997da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            } else {
4998da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                data = mBuffer->data();
4999da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
500005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        } else {
5001da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            int32_t max_size;
5002da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mFormat == NULL
5003da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    || !mFormat->findInt32(kKeyMaxInputSize, &max_size)
5004da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    || !isInRange((size_t)0u, (size_t)max_size, size)) {
5005da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = true;
5006da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            } else {
5007da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                data = mSrcBuffer;
5008da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
500905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
501005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
5011da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        if (isMalFormed || data == NULL) {
5012da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            ALOGE("isMalFormed size %zu", size);
5013da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mBuffer != NULL) {
5014da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer->release();
5015da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer = NULL;
5016da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
5017da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            return ERROR_MALFORMED;
5018da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        }
5019da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        num_bytes_read = mDataSource->readAt(offset, data, size);
5020da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
502105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (num_bytes_read < (ssize_t)size) {
502205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
502305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
502405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
5025da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            ALOGE("i/o error");
502605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_IO;
502705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
502805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
502905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (usesDRM) {
503005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
503105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, size);
503205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
503305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        } else {
503405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            uint8_t *dstData = (uint8_t *)mBuffer->data();
503505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            size_t srcOffset = 0;
503605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            size_t dstOffset = 0;
503705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
503805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            while (srcOffset < size) {
5039da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
504005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                size_t nalLength = 0;
504105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (!isMalFormed) {
504205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
504305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    srcOffset += mNALLengthSize;
5044da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
5045da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
5046da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
504705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
504805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
504905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (isMalFormed) {
5050da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    ALOGE("Video is malformed; nalLength %zu", nalLength);
505105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    mBuffer->release();
505205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    mBuffer = NULL;
505305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return ERROR_MALFORMED;
505405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
505505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
505605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (nalLength == 0) {
505705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    continue;
505805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
505905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
50605403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                if (dstOffset > SIZE_MAX - 4 ||
50615403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                        dstOffset + 4 > SIZE_MAX - nalLength ||
50625403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                        dstOffset + 4 + nalLength > mBuffer->size()) {
50635403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
50645403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    android_errorWriteLog(0x534e4554, "26365349");
50655403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    mBuffer->release();
50665403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    mBuffer = NULL;
50675403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    return ERROR_MALFORMED;
50685403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                }
506905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
507005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
507105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
507205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
507305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 1;
507405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
507505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                srcOffset += nalLength;
507605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstOffset += nalLength;
507705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
507805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK_EQ(srcOffset, size);
507905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
508005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, dstOffset);
508105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
508205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
508305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer->meta_data()->setInt64(
508405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
5085170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        mBuffer->meta_data()->setInt64(
5086170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
508705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
508805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (targetSampleTimeUs >= 0) {
508905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt64(
509005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    kKeyTargetTime, targetSampleTimeUs);
509105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
509205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
509305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (isSyncSample) {
509405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
509505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
509605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
509705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ++mCurrentSampleIndex;
509805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
509905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        *out = mBuffer;
510005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer = NULL;
510105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
510205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
510305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
510405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
510505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
5106bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
5107bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        const char *mimePrefix) {
5108bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    for (Track *track = mFirstTrack; track != NULL; track = track->next) {
5109bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        const char *mime;
5110bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        if (track->meta != NULL
5111bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                && track->meta->findCString(kKeyMIMEType, &mime)
5112bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
5113bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber            return track;
5114bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        }
5115bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    }
5116bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber
5117bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    return NULL;
5118bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber}
5119bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber
51201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4(
5121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
512220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
512320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
512434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    ssize_t n = source->readAt(4, header, sizeof(header));
512520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (n < (ssize_t)sizeof(header)) {
512620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
512720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
512820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
512920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
5130b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
5131b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
51320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
5133ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
5134983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
513518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
51365a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        *confidence = 0.4;
513720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
513820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return true;
513920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
514020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
514120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return false;
514220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
514320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) {
51451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    static const uint32_t kCompatibleBrands[] = {
51461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', 'm'),
51471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', '2'),
51481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('a', 'v', 'c', '1'),
51493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        FOURCC('h', 'v', 'c', '1'),
51503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        FOURCC('h', 'e', 'v', '1'),
51511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('3', 'g', 'p', '4'),
51521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '1'),
51531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '2'),
51544cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong
51554cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        // Won't promise that the following file types can be played.
51564cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        // Just give these file types a chance.
51574cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
51584cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
515958fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber
516058fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber        FOURCC('3', 'g', '2', 'a'),  // 3GPP2
516158fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber        FOURCC('3', 'g', '2', 'b'),
51621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    };
51631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
51641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    for (size_t i = 0;
51651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
51661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         ++i) {
51671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        if (kCompatibleBrands[i] == fourcc) {
51681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            return true;
51691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
51701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
51711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
51721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
51731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
51741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
51751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable
51761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present.
5177a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends
5178a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of
5179a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata.
51801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4(
5181a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5182a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        sp<AMessage> *meta) {
5183a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    // We scan up to 128 bytes to identify this file as an MP4.
5184a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    static const off64_t kMaxScanOffset = 128ll;
51851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5186a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    off64_t offset = 0ll;
5187a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    bool foundGoodFileType = false;
5188a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    off64_t moovAtomEndOffset = -1ll;
5189a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    bool done = false;
51901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5191a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    while (!done && offset < kMaxScanOffset) {
5192a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint32_t hdr[2];
5193a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        if (source->readAt(offset, hdr, 8) < 8) {
5194a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            return false;
5195a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        }
5196a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5197a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint64_t chunkSize = ntohl(hdr[0]);
5198a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint32_t chunkType = ntohl(hdr[1]);
5199a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        off64_t chunkDataOffset = offset + 8;
5200a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5201a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        if (chunkSize == 1) {
5202a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
52031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                return false;
52041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
52051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5206a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            chunkSize = ntoh64(chunkSize);
5207a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            chunkDataOffset += 8;
5208a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5209a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            if (chunkSize < 16) {
5210a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                // The smallest valid chunk is 16 bytes long in this case.
5211a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                return false;
5212a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            }
5213452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen
5214a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        } else if (chunkSize < 8) {
5215a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            // The smallest valid chunk is 8 bytes long.
5216a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            return false;
5217a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        }
5218a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5219452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        // (data_offset - offset) is either 8 or 16
5220452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset);
5221452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        if (chunkDataSize < 0) {
5222452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen            ALOGE("b/23540914");
5223452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen            return ERROR_MALFORMED;
5224452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        }
5225a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
522605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        char chunkstring[5];
522705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MakeFourCCString(chunkType, chunkstring);
5228ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
5229a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        switch (chunkType) {
5230a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            case FOURCC('f', 't', 'y', 'p'):
5231a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            {
5232a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                if (chunkDataSize < 8) {
5233a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    return false;
5234a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
5235a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5236a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
5237a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
5238a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (i == 1) {
5239a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // Skip this index, it refers to the minorVersion,
5240a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // not a brand.
5241a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        continue;
5242a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
5243a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5244a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    uint32_t brand;
5245a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (source->readAt(
5246a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
5247a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        return false;
5248a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
5249a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5250a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    brand = ntohl(brand);
5251a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5252a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (isCompatibleBrand(brand)) {
5253a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        foundGoodFileType = true;
5254a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        break;
5255a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
5256a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
5257a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5258a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                if (!foundGoodFileType) {
5259a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    return false;
5260a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
5261a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
52621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                break;
52631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
5264a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5265a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            case FOURCC('m', 'o', 'o', 'v'):
5266a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            {
5267a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                moovAtomEndOffset = offset + chunkSize;
5268a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5269a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                done = true;
5270a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                break;
5271a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            }
5272a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5273a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            default:
5274a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                break;
52751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
5276a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5277a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        offset += chunkSize;
52781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
52791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5280a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (!foundGoodFileType) {
52811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return false;
52821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
52831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
52841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
52855a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    *confidence = 0.4f;
52861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5287a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (moovAtomEndOffset >= 0) {
5288a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        *meta = new AMessage;
5289a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
5290a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5291ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset);
5292a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    }
5293a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
52941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return true;
52951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
52961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
52971b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4(
52985a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5299a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        sp<AMessage> *meta) {
5300a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
53011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
53021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
53031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
53041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (LegacySniffMPEG4(source, mimeType, confidence)) {
53055ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
53061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
53071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
53081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
53091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
53101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
53111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
531220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
5313