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)) {
472423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen            // MPEG2 tracks do not provide CSD, so read the stream header
473423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen            if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
474423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                off64_t offset;
475423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                size_t size;
476423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                if (track->sampleTable->getMetaDataForSample(
477423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                            0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
478423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                    if (size > kMaxTrackHeaderSize) {
479423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                        size = kMaxTrackHeaderSize;
480423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                    }
481423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                    uint8_t header[kMaxTrackHeaderSize];
482423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                    if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
483423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                        track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
484423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                    }
485423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen                }
486423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen            }
487423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen
48805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (mMoofOffset > 0) {
48905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                int64_t duration;
49005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (track->meta->findInt64(kKeyDuration, &duration)) {
49105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    // nothing fancy, just pick a frame near 1/4th of the duration
49205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    track->meta->setInt64(
49305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            kKeyThumbnailTime, duration / 4);
49405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
49505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            } else {
49605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t sampleIndex;
49705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t sampleTime;
4980d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                if (track->timescale != 0 &&
4990d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                        track->sampleTable->findThumbnailSample(&sampleIndex) == OK
50005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        && track->sampleTable->getMetaDataForSample(
50105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            sampleIndex, NULL /* offset */, NULL /* size */,
50205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            &sampleTime) == OK) {
50305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    track->meta->setInt64(
50405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            kKeyThumbnailTime,
50505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                            ((int64_t)sampleTime * 1000000) / track->timescale);
50605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
5077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            }
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) {
1243ab34612a31e82b713ca0ac043e14f68f3788fbdaMarco Nelissen                delete[] pssh.data;
1244ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
1245ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
1246ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mPssh.push_back(pssh);
1247ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
1248ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
1249ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
1250ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'h', 'd'):
125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
12530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
12540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1255202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih            if (chunk_data_size < 4 || mLastTrack == NULL) {
125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t version;
126034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, &version, sizeof(version))
126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(version)) {
126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
126520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1266c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t timescale_offset;
126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 16;
127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else if (version == 0) {
127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 8;
127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
127320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t timescale;
127734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        timescale_offset, &timescale, sizeof(timescale))
127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(timescale)) {
128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
128120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12832e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang            if (!timescale) {
12842e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang                ALOGE("timescale should not be ZERO.");
12852e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang                return ERROR_MALFORMED;
12862e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang            }
12872e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang
128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->timescale = ntohl(timescale);
128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1290c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            // 14496-12 says all ones means indeterminate, but some files seem to use
1291c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            // 0 instead. We treat both the same.
129205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            int64_t duration = 0;
129320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
129434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration, sizeof(duration))
129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration)) {
129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
1299c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration != -1) {
1300c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = ntoh64(duration);
1301c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
130305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                uint32_t duration32;
130434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration32, sizeof(duration32))
130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration32)) {
130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
130905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (duration32 != 0xffffffff) {
131005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    duration = ntohl(duration32);
131105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1313e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake            if (duration != 0 && mLastTrack->timescale != 0) {
1314c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mLastTrack->meta->setInt64(
1315c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                        kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
1316c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
131720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            uint8_t lang[2];
13197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            off64_t lang_offset;
13207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (version == 1) {
13217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                lang_offset = timescale_offset + 4 + 8;
13227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else if (version == 0) {
13237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                lang_offset = timescale_offset + 4 + 4;
13247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else {
13257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return ERROR_IO;
13267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
13297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                    < (ssize_t)sizeof(lang)) {
13307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return ERROR_IO;
13317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // To get the ISO-639-2/T three character language code
13347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // 1 bit pad followed by 3 5-bits characters. Each character
13357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            // is packed as the difference between its ASCII value and 0x60.
13367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            char lang_code[4];
13377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
13387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
13397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[2] = (lang[1] & 0x1f) + 0x60;
13407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            lang_code[3] = '\0';
13417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            mLastTrack->meta->setCString(
13437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                    kKeyMediaLanguage, lang_code);
13447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'd'):
134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8];
1351c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            if (chunk_data_size < (off64_t)sizeof(buffer)) {
1352bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1353bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
1354bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
135534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, 8) < 8) {
135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t entry_count = U32_AT(&buffer[4]);
136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (entry_count > 1) {
13683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // For 3GPP timed text, there could be multiple tx3g boxes contain
13693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // multiple text display formats. These formats will be used to
13703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                // display the timed text.
1371ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // For encrypted files, there may also be more than one entry.
13723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                const char *mime;
1373f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1374f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                if (mLastTrack == NULL)
1375f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                    return ERROR_MALFORMED;
1376f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
13773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1378ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
1379ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                        strcasecmp(mime, "application/octet-stream")) {
13803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    // For now we only support a single type of media per track.
13813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    mLastTrack->skipTrack = true;
13823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    *offset += chunk_size;
13833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    break;
13843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                }
138520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1386c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
138720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + 8;
138820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            for (uint32_t i = 0; i < entry_count; ++i) {
138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
139020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
139320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1394bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1395bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1396bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1397bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
1400e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang        case FOURCC('m', 'e', 't', 't'):
1401e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang        {
1402e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            *offset += chunk_size;
1403e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang
1404e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            if (mLastTrack == NULL)
1405e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang                return ERROR_MALFORMED;
1406e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang
1407e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
1408e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            if (buffer->data() == NULL) {
1409e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang                return NO_MEMORY;
1410e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            }
1411e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang
1412e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            if (mDataSource->readAt(
1413e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
1414e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang                return ERROR_IO;
1415e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            }
1416e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang
1417e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            String8 mimeFormat((const char *)(buffer->data()), chunk_data_size);
1418e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            mLastTrack->meta->setCString(kKeyMIMEType, mimeFormat.string());
1419e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang
1420e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang            break;
1421e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang        }
142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
142448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        case FOURCC('e', 'n', 'c', 'a'):
142520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
1426371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1428bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')
1429bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) {
1430bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                // Ignore mp4a embedded in QT wave atom
1431bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                *offset += chunk_size;
1432bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                break;
1433bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
1434bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
143520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8 + 20];
143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic AudioSampleEntry size.
143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
144134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1446b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
1447bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            uint16_t version = U16_AT(&buffer[8]);
144848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint32_t num_channels = U16_AT(&buffer[16]);
144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
145081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint16_t sample_size = U16_AT(&buffer[18]);
145181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
145281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
1453f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1454f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1455f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1456bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            off64_t stop_offset = *offset + chunk_size;
1457bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            *offset = data_offset + sizeof(buffer);
1458bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
1459bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')) {
1460bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (version == 1) {
1461bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    if (mDataSource->readAt(*offset, buffer, 16) < 16) {
1462bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                        return ERROR_IO;
1463bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    }
1464bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
1465bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#if 0
1466bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(buffer);  // samples per packet
1467bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&buffer[4]);  // bytes per packet
1468bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&buffer[8]);  // bytes per frame
1469bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&buffer[12]);  // bytes per sample
1470bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#endif
1471bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    *offset += 16;
1472bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                } else if (version == 2) {
1473bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    uint8_t v2buffer[36];
1474bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    if (mDataSource->readAt(*offset, v2buffer, 36) < 36) {
1475bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                        return ERROR_IO;
1476bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    }
1477bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
1478bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#if 0
1479bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(v2buffer);  // size of struct only
1480bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    sample_rate = (uint32_t)U64_AT(&v2buffer[4]);  // audio sample rate
1481bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    num_channels = U32_AT(&v2buffer[12]);  // num audio channels
1482bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[16]);  // always 0x7f000000
1483bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    sample_size = (uint16_t)U32_AT(&v2buffer[20]);  // const bits per channel
1484bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[24]);  // format specifc flags
1485bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[28]);  // const bytes per audio packet
1486bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    U32_AT(&v2buffer[32]);  // const LPCM frames per audio packet
1487bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#endif
1488bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    *offset += 36;
1489bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
1490bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
1491bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
149248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
149348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                // if the chunk type is enca, we'll get the type from the sinf/frma box later
149448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
149548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
149748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
149881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                   chunk, num_channels, sample_size, sample_rate);
149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
150020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
150120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
150220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
150720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1508bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1509bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1510bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1511bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
151220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
151320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
1516ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('e', 'n', 'c', 'v'):
151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
1518e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('H', '2', '6', '3'):
1519e071b055cee301d71335519601474c62b10af411James Dong        case FOURCC('h', '2', '6', '3'):
152020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
15213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', '1'):
15223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'e', 'v', '1'):
152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[78];
152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
152620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic VideoSampleEntry size.
152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
153034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
153220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1535b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
153620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t width = U16_AT(&buffer[6 + 18]);
153720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t height = U16_AT(&buffer[6 + 20]);
153820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // The video sample is not standard-compliant if it has invalid dimension.
1540a6256238d9015c42129fe43791968768fe501efaJames Dong            // Use some default width and height value, and
1541a6256238d9015c42129fe43791968768fe501efaJames Dong            // let the decoder figure out the actual width and height (and thus
1542a6256238d9015c42129fe43791968768fe501efaJames Dong            // be prepared for INFO_FOMRAT_CHANGED event).
1543a6256238d9015c42129fe43791968768fe501efaJames Dong            if (width == 0)  width  = 352;
1544a6256238d9015c42129fe43791968768fe501efaJames Dong            if (height == 0) height = 288;
1545a6256238d9015c42129fe43791968768fe501efaJames Dong
1546134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            // printf("*** coding='%s' width=%d height=%d\n",
1547134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            //        chunk, width, height);
154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1549f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1550f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1551f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1552ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
1553ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                // if the chunk type is encv, we'll get the type from the sinf/frma box later
1554ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1555ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
155620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyWidth, width);
155720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyHeight, height);
155820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1559c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t stop_offset = *offset + chunk_size;
156020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + sizeof(buffer);
156120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
156220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
156320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
1567bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1568bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1569bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1570bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
157120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
157220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
157320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
157420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'c', 'o'):
157520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('c', 'o', '6', '4'):
157620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1577274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1578274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1579274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
158020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setChunkOffsetParams(
158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15840517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
15850517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
158620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
158720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
158820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
158920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
159020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
159120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
159220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
159320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'c'):
159420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1595274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1596274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1597274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
159820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
159920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleToChunkParams(
160020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
160120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16020517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16030517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
160420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
160520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
160620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
160720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
160820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
160920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
161020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
161120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'z'):
161220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'z', '2'):
161320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1614274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1615274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1616274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleSizeParams(
161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
16220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
162320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
162420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
162520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1627738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            size_t max_size;
162849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
162949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber
163049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            if (err != OK) {
163149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber                return err;
163249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            }
1633738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
163405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (max_size != 0) {
163505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // Assume that a given buffer only contains at most 10 chunks,
163605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // each chunk originally prefixed with a 2 byte length will
163705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
163805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // and thus will grow by 2 bytes per chunk.
1639beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                if (max_size > SIZE_MAX - 10 * 2) {
1640beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    ALOGE("max sample size too big: %zu", max_size);
1641beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    return ERROR_MALFORMED;
1642beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                }
164305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
164405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            } else {
164505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                // No size was specified. Pick a conservatively large size.
1646beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                uint32_t width, height;
1647beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) ||
1648beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) {
164905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    ALOGE("No width or height, assuming worst case 1080p");
1650f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    width = 1920;
1651f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    height = 1080;
1652beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                } else {
1653beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // A resolution was specified, check that it's not too big. The values below
1654beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // were chosen so that the calculations below don't cause overflows, they're
1655beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    // not indicating that resolutions up to 32kx32k are actually supported.
1656beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    if (width > 32768 || height > 32768) {
1657beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                        ALOGE("can't support %u x %u video", width, height);
1658beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                        return ERROR_MALFORMED;
1659beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen                    }
166005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
1661f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar
16624256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen                const char *mime;
16634256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
166407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
166507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
166607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    // AVC & HEVC requires compression ratio of at least 2, and uses
1667f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // macroblocks
1668f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192;
1669f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                } else {
1670f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // For all other formats there is no minimum compression
1671f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    // ratio. Use compression ratio of 1.
1672f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                    max_size = width * height * 3 / 2;
167305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
1674f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar                mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
167505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
1676113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong
16774256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen            // NOTE: setting another piece of metadata invalidates any pointers (such as the
16784256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen            // mimetype) previously obtained, so don't cache them.
1679113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            const char *mime;
1680113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1681113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            // Calculate average frame rate.
1682113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            if (!strncasecmp("video/", mime, 6)) {
1683113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                size_t nSamples = mLastTrack->sampleTable->countSamples();
1684949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                if (nSamples == 0) {
1685949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    int32_t trackId;
1686949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) {
1687949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        for (size_t i = 0; i < mTrex.size(); i++) {
1688949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            Trex *t = &mTrex.editItemAt(i);
1689949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            if (t->track_ID == (uint32_t) trackId) {
1690949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                if (t->default_sample_duration > 0) {
1691949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                    int32_t frameRate =
1692949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                            mLastTrack->timescale / t->default_sample_duration;
1693949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                    mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1694949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                }
1695949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                break;
1696949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            }
1697949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        }
1698949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    }
1699949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                } else {
1700949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    int64_t durationUs;
1701949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                    if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
1702949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        if (durationUs > 0) {
1703949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            int32_t frameRate = (nSamples * 1000000LL +
1704949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                                        (durationUs >> 1)) / durationUs;
1705949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                            mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1706949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen                        }
1707113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                    }
1708113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong                }
1709113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong            }
1710113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong
171120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
171220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
171320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
171420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 't', 's'):
171520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1716274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1717274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1718274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
17190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
172220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setTimeToSampleParams(
172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
172920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17324931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        case FOURCC('c', 't', 't', 's'):
17334931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        {
1734274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1735274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1736274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
17370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
17394931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            status_t err =
17404931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                mLastTrack->sampleTable->setCompositionTimeToSampleParams(
17414931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                        data_offset, chunk_data_size);
17424931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
17434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            if (err != OK) {
17444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                return err;
17454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            }
17464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
17474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            break;
17484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        }
17494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
175020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 's'):
175120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
1752274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
1753274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake                return ERROR_MALFORMED;
1754274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake
17550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
175720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
175820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSyncSampleParams(
175920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
176020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
176120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
176220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
176320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
176420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
176520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
176620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
176720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1768afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        // \xA9xyz
1769e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh        case FOURCC(0xA9, 'x', 'y', 'z'):
17704948818cb91176df74c972ac27b2f392b5d148bcJames Dong        {
17710517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
17720517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1773afd492436efc7f66b958da14659b52232efa5910Marco Nelissen            // Best case the total data length inside "\xA9xyz" box
1774afd492436efc7f66b958da14659b52232efa5910Marco Nelissen            // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/",
17754948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // where "\x00\x04" is the text string length with value = 4,
17764948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // "\0x15\xc7" is the language code = en, and "0+0" is a
17774948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // location (string) value with longitude = 0 and latitude = 0.
17784948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (chunk_data_size < 8) {
17794948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_MALFORMED;
17804948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17814948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17824948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // Worst case the location string length would be 18,
17834948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // for instance +90.0000-180.0000, without the trailing "/" and
178423b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney            // the string length + language code, and some devices include
178523b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney            // an additional 8 bytes of altitude, e.g. +007.186
178623b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney            char buffer[18 + 8];
17874948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17884948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // Substracting 5 from the data size is because the text string length +
17894948818cb91176df74c972ac27b2f392b5d148bcJames Dong            // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
17904948818cb91176df74c972ac27b2f392b5d148bcJames Dong            off64_t location_length = chunk_data_size - 5;
17914948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (location_length >= (off64_t) sizeof(buffer)) {
17924948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_MALFORMED;
17934948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17944948818cb91176df74c972ac27b2f392b5d148bcJames Dong
17954948818cb91176df74c972ac27b2f392b5d148bcJames Dong            if (mDataSource->readAt(
17964948818cb91176df74c972ac27b2f392b5d148bcJames Dong                        data_offset + 4, buffer, location_length) < location_length) {
17974948818cb91176df74c972ac27b2f392b5d148bcJames Dong                return ERROR_IO;
17984948818cb91176df74c972ac27b2f392b5d148bcJames Dong            }
17994948818cb91176df74c972ac27b2f392b5d148bcJames Dong
18004948818cb91176df74c972ac27b2f392b5d148bcJames Dong            buffer[location_length] = '\0';
18014948818cb91176df74c972ac27b2f392b5d148bcJames Dong            mFileMetaData->setCString(kKeyLocation, buffer);
18024948818cb91176df74c972ac27b2f392b5d148bcJames Dong            break;
18034948818cb91176df74c972ac27b2f392b5d148bcJames Dong        }
18044948818cb91176df74c972ac27b2f392b5d148bcJames Dong
180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('e', 's', 'd', 's'):
180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
18070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
18080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 4) {
181020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
181220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[256];
1814c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            if (chunk_data_size > (off64_t)sizeof(buffer)) {
181520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
181620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
181720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
181834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
181920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
182020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
182120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
182220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
182320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
182420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
182520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
182620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
182720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1828f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1829f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1830f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
183120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
183220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
183320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1834ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            if (mPath.size() >= 2
1835ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1836ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // Information from the ESDS must be relied on for proper
1837ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // setup of sample rate and channel count for MPEG4 Audio.
1838ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // The generic header appears to only contain generic
1839ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // information...
1840ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1841ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1842ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        &buffer[4], chunk_data_size - 4);
1843ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1844ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                if (err != OK) {
1845ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    return err;
1846ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                }
1847ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            }
1848ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            if (mPath.size() >= 2
1849ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) {
1850ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                // Check if the video is MPEG2
1851ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                ESDS esds(&buffer[4], chunk_data_size - 4);
1852ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar
1853ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                uint8_t objectTypeIndication;
1854ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) {
1855ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) {
1856ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
1857ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                    }
1858ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar                }
1859ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            }
186020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
186120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
186220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
186346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        case FOURCC('b', 't', 'r', 't'):
186446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        {
186546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            *offset += chunk_size;
1866fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa            if (mLastTrack == NULL) {
1867fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa                return ERROR_MALFORMED;
1868fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa            }
186946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
187046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint8_t buffer[12];
187146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (chunk_data_size != sizeof(buffer)) {
187246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                return ERROR_MALFORMED;
187346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
187446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
187546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (mDataSource->readAt(
187646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
187746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                return ERROR_IO;
187846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
187946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
188046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint32_t maxBitrate = U32_AT(&buffer[4]);
188146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            uint32_t avgBitrate = U32_AT(&buffer[8]);
188246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
188346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
188446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
188546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
188646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
188746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
188846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            break;
188946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        }
189020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
189120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', 'C'):
189220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
18930517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
18940517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
1895d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
189620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18976a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            if (buffer->data() == NULL) {
18986a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                ALOGE("b/28471206");
18996a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                return NO_MEMORY;
19006a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            }
19016a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen
190234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
1903d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
190420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
190520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
190620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1907f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1908f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1909f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
191020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
1911d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson                    kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size);
191220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
191320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
191420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        case FOURCC('h', 'v', 'c', 'C'):
19163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        {
19173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            sp<ABuffer> buffer = new ABuffer(chunk_data_size);
19183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
19196a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            if (buffer->data() == NULL) {
19206a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                ALOGE("b/28471206");
19216a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                return NO_MEMORY;
19226a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen            }
19236a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen
19243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            if (mDataSource->readAt(
19253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                        data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
19263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                return ERROR_IO;
19273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
19283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
1929f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1930f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1931f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
19323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            mLastTrack->meta->setData(
19333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                    kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size);
19343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
19353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            *offset += chunk_size;
19363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            break;
19373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
193820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1939244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        case FOURCC('d', '2', '6', '3'):
1940244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        {
19410517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
194217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            /*
194317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * d263 contains a fixed 7 bytes part:
194417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   vendor - 4 bytes
194517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   version - 1 byte
194617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   level - 1 byte
194717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   profile - 1 byte
194817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * optionally, "d263" box itself may contain a 16-byte
194917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             * bit rate box (bitr)
195017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   average bit rate - 4 bytes
195117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             *   max bit rate - 4 bytes
195217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong             */
195317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            char buffer[23];
195417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong            if (chunk_data_size != 7 &&
195517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong                chunk_data_size != 23) {
1956ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size);
1957244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                return ERROR_MALFORMED;
1958244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            }
1959244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1960244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            if (mDataSource->readAt(
1961244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
1962244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong                return ERROR_IO;
1963244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            }
1964244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1965f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
1966f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
1967f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
1968244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
1969244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
1970244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong            break;
1971244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong        }
1972244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong
197372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'e', 't', 'a'):
197472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
19758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            off64_t stop_offset = *offset + chunk_size;
19768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            *offset = data_offset;
19778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            bool isParsingMetaKeys = underQTMetaPath(mPath, 2);
19788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (!isParsingMetaKeys) {
19798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                uint8_t buffer[4];
19808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (chunk_data_size < (off64_t)sizeof(buffer)) {
19818ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return ERROR_MALFORMED;
19838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
1984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
19858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (mDataSource->readAt(
19868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                            data_offset, buffer, 4) < 4) {
19878ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return ERROR_IO;
19898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
199072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
19918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                if (U32_AT(buffer) != 0) {
19928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // Should be version 0, flags 0.
1993ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
19948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // If it's not, let's assume this is one of those
19958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // apparently malformed chunks that don't have flags
19968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // and completely different semantics than what's
19978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    // in the MPEG4 specs and skip it.
19988ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen                    *offset = stop_offset;
19998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                    return OK;
20008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                }
20018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                *offset +=  sizeof(buffer);
200272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
200372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
200472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            while (*offset < stop_offset) {
200572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                status_t err = parseChunk(offset, depth + 1);
200672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
200772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
200872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
200972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
2010bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
2011bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
2012bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
2013bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
201472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
201572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
201672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
20175d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('m', 'e', 'a', 'n'):
20185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('n', 'a', 'm', 'e'):
201972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('d', 'a', 't', 'a'):
202072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
20210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
20220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
202372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
2024fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                status_t err = parseITunesMetaData(data_offset, chunk_data_size);
202572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
202672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
202772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
202872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
202972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
203072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
203172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
203272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
203372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
203472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'v', 'h', 'd'):
203572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
20360517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
20370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
20380d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen            if (depth != 1) {
20390d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                ALOGE("mvhd: depth %d", depth);
20400d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen                return ERROR_MALFORMED;
20410d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen            }
2042c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 32) {
204372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_MALFORMED;
204472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
204572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2046c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint8_t header[32];
204772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mDataSource->readAt(
204872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                        data_offset, header, sizeof(header))
204972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    < (ssize_t)sizeof(header)) {
205072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_IO;
205172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
205272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2053fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen            uint64_t creationTime;
2054c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint64_t duration = 0;
205572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (header[0] == 1) {
205672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U64_AT(&header[4]);
2057fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                mHeaderTimescale = U32_AT(&header[20]);
2058c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = U64_AT(&header[24]);
2059c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration == 0xffffffffffffffff) {
2060c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = 0;
2061c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2062bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (header[0] != 0) {
2063bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
206472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            } else {
206572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U32_AT(&header[4]);
2066fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen                mHeaderTimescale = U32_AT(&header[12]);
2067c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                uint32_t d32 = U32_AT(&header[16]);
2068c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (d32 == 0xffffffff) {
2069c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    d32 = 0;
2070c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2071c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = d32;
2072c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
20733724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
2074c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
207572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
207672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
207772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            String8 s;
20783724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            if (convertTimeToDate(creationTime, &s)) {
20793724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen                mFileMetaData->setCString(kKeyDate, s.string());
20803724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen            }
208172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
208272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
208372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
208472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
208572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2086c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        case FOURCC('m', 'e', 'h', 'd'):
2087c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        {
2088c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            *offset += chunk_size;
2089c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2090c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 8) {
2091c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_MALFORMED;
2092c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2093c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2094c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint8_t flags[4];
2095c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (mDataSource->readAt(
2096c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                        data_offset, flags, sizeof(flags))
2097c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    < (ssize_t)sizeof(flags)) {
2098c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2099c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2100c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2101c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            uint64_t duration = 0;
2102c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (flags[0] == 1) {
2103c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                // 64 bit
2104c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (chunk_data_size < 12) {
2105c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    return ERROR_MALFORMED;
2106c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2107c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mDataSource->getUInt64(data_offset + 4, &duration);
2108c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (duration == 0xffffffffffffffff) {
2109c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    duration = 0;
2110c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2111c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            } else if (flags[0] == 0) {
2112c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                // 32 bit
2113c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                uint32_t d32;
2114c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mDataSource->getUInt32(data_offset + 4, &d32);
2115c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                if (d32 == 0xffffffff) {
2116c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                    d32 = 0;
2117c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                }
2118c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                duration = d32;
2119c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            } else {
2120c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_MALFORMED;
2121c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2122c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2123e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake            if (duration != 0 && mHeaderTimescale != 0) {
2124c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
2125c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2126c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2127c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            break;
2128c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
2129c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2130dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        case FOURCC('m', 'd', 'a', 't'):
2131dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        {
2132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("mdat chunk, drm: %d", mIsDrm);
2133928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
2134928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang            mMdatFound = true;
2135928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang
2136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (!mIsDrm) {
2137dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                *offset += chunk_size;
2138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                break;
2139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
2140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2141dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (chunk_size < 8) {
2142dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
2143dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
2144dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2145dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return parseDrmSINF(offset, data_offset);
2146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
2147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
21483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        case FOURCC('h', 'd', 'l', 'r'):
21493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        {
21500517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
21510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2152ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang            if (underQTMetaPath(mPath, 3)) {
2153ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang                break;
2154ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang            }
2155ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang
21563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t buffer;
21573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (mDataSource->readAt(
21583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                        data_offset + 8, &buffer, 4) < 4) {
21593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                return ERROR_IO;
21603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t type = ntohl(buffer);
21633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            // For the 3GPP file format, the handler-type within the 'hdlr' box
2164e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            // shall be 'text'. We also want to support 'sbtl' handler type
2165e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            // for a practical reason as various MPEG4 containers use it.
2166e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang            if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
2167cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                if (mLastTrack != NULL) {
2168cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                    mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
2169cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar                }
21703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
21713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            break;
21733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang        }
21743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
21758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        case FOURCC('k', 'e', 'y', 's'):
21768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        {
21778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            *offset += chunk_size;
21788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
21798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (underQTMetaPath(mPath, 3)) {
2180ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                status_t err = parseQTMetaKey(data_offset, chunk_data_size);
2181ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                if (err != OK) {
2182ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    return err;
2183ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                }
21848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            }
21858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            break;
21868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
21878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
2188c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        case FOURCC('t', 'r', 'e', 'x'):
2189c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        {
2190c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            *offset += chunk_size;
2191c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2192c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (chunk_data_size < 24) {
2193c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2194c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2195c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            Trex trex;
2196c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) ||
2197c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) ||
2198c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) ||
2199c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) ||
2200c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) {
2201c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                return ERROR_IO;
2202c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
2203c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mTrex.add(trex);
2204c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            break;
2205c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
2206c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
22077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        case FOURCC('t', 'x', '3', 'g'):
22087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        {
2209f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            if (mLastTrack == NULL)
2210f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                return ERROR_MALFORMED;
2211f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
22123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            uint32_t type;
22133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            const void *data;
22143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            size_t size = 0;
22153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (!mLastTrack->meta->findData(
22163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    kKeyTextFormatData, &type, &data, &size)) {
22173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                size = 0;
22183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
22193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22200e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich            if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
2221dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake                return ERROR_MALFORMED;
2222dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake            }
2223dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake
22248da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
22258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            if (buffer == NULL) {
22268da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen                return ERROR_MALFORMED;
22278da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen            }
22283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if (size > 0) {
22303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                memcpy(buffer, data, size);
22313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
22323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
22343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    < chunk_size) {
22353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                delete[] buffer;
22363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                buffer = NULL;
22373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen                // advance read pointer so we don't end up reading this again
22390517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen                *offset += chunk_size;
22403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                return ERROR_IO;
22413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            }
22423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            mLastTrack->meta->setData(
22443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang                    kKeyTextFormatData, 0, buffer, size + chunk_size);
22453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang
22463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang            delete[] buffer;
22477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
22487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            *offset += chunk_size;
22497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            break;
22507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
22517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2252515e855eae78aa495da58356486aaa666cb57fd1James Dong        case FOURCC('c', 'o', 'v', 'r'):
2253515e855eae78aa495da58356486aaa666cb57fd1James Dong        {
22540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
22550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2256515e855eae78aa495da58356486aaa666cb57fd1James Dong            if (mFileMetaData != NULL) {
2257635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64,
2258635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                      chunk_data_size, data_offset);
22591e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake
2260635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert                if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) {
22611e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake                    return ERROR_MALFORMED;
22621e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake                }
22631552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
22646a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                if (buffer->data() == NULL) {
22656a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                    ALOGE("b/28471206");
22666a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                    return NO_MEMORY;
22676a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen                }
2268515e855eae78aa495da58356486aaa666cb57fd1James Dong                if (mDataSource->readAt(
22691552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                    data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
2270515e855eae78aa495da58356486aaa666cb57fd1James Dong                    return ERROR_IO;
2271515e855eae78aa495da58356486aaa666cb57fd1James Dong                }
2272515e855eae78aa495da58356486aaa666cb57fd1James Dong                const int kSkipBytesOfDataBox = 16;
227397d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                if (chunk_data_size <= kSkipBytesOfDataBox) {
227497d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                    return ERROR_MALFORMED;
227597d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake                }
227697d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake
2277515e855eae78aa495da58356486aaa666cb57fd1James Dong                mFileMetaData->setData(
2278515e855eae78aa495da58356486aaa666cb57fd1James Dong                    kKeyAlbumArt, MetaData::TYPE_NONE,
22791552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin                    buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
2280515e855eae78aa495da58356486aaa666cb57fd1James Dong            }
2281515e855eae78aa495da58356486aaa666cb57fd1James Dong
2282515e855eae78aa495da58356486aaa666cb57fd1James Dong            break;
2283515e855eae78aa495da58356486aaa666cb57fd1James Dong        }
2284515e855eae78aa495da58356486aaa666cb57fd1James Dong
228558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        case FOURCC('c', 'o', 'l', 'r'):
228658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        {
228758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            *offset += chunk_size;
228858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
228958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            // ignore otherwise
229058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
229158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                status_t err = parseColorInfo(data_offset, chunk_data_size);
229258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                if (err != OK) {
229358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                    return err;
229458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                }
229558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            }
229658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
229758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            break;
229858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        }
229958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
2300fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('t', 'i', 't', 'l'):
2301fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('p', 'e', 'r', 'f'):
2302fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'u', 't', 'h'):
2303fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('g', 'n', 'r', 'e'):
2304fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'l', 'b', 'm'):
2305fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('y', 'r', 'r', 'c'):
2306fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
23070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
23080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2309fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
2310fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2311fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (err != OK) {
2312fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                return err;
2313fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
2314fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2315fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
2316fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
2317fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
2318328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        case FOURCC('I', 'D', '3', '2'):
2319328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        {
23200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen            *offset += chunk_size;
23210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen
2322328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            if (chunk_data_size < 6) {
2323328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                return ERROR_MALFORMED;
2324328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            }
2325328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2326328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            parseID3v2MetaData(data_offset + 6);
2327328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
2328328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            break;
2329328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
2330328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
23315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('-', '-', '-', '-'):
23325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        {
23335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentMean.clear();
23345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentName.clear();
23355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            mLastCommentData.clear();
23365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            *offset += chunk_size;
23375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            break;
23385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        }
23395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen
234005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('s', 'i', 'd', 'x'):
234105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        {
2342ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseSegmentIndex(data_offset, chunk_data_size);
2343ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
2344ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
2345ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
234605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset += chunk_size;
234705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return UNKNOWN_ERROR; // stop parsing after sidx
234805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
234905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2350bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        case FOURCC('a', 'c', '-', '3'):
2351bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        {
2352bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa            *offset += chunk_size;
2353bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa            return parseAC3SampleEntry(data_offset);
2354bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        }
2355bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2356bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        case FOURCC('f', 't', 'y', 'p'):
2357bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        {
2358bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            if (chunk_data_size < 8 || depth != 0) {
2359bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                return ERROR_MALFORMED;
2360bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
2361bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2362bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            off64_t stop_offset = *offset + chunk_size;
2363bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4;
2364bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
2365bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (i == 1) {
2366bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    // Skip this index, it refers to the minorVersion,
2367bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    // not a brand.
2368bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    continue;
2369bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
2370bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2371bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                uint32_t brand;
2372bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (mDataSource->readAt(data_offset + 4 * i, &brand, 4) < 4) {
2373bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    return ERROR_MALFORMED;
2374bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
2375bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2376bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                brand = ntohl(brand);
2377bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                if (brand == FOURCC('q', 't', ' ', ' ')) {
2378bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    mIsQT = true;
2379bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                    break;
2380bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia                }
2381bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            }
2382bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2383bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            *offset = stop_offset;
2384bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
2385bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia            break;
2386bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia        }
2387bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia
238820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
238920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
23908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            // check if we're parsing 'ilst' for meta keys
23918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            // if so, treat type as a number (key-id).
23928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            if (underQTMetaPath(mPath, 3)) {
2393ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
2394ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                if (err != OK) {
2395ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    return err;
2396ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                }
23978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            }
23988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
239920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
240020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
240120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
240220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
240320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
240420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
240520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
240620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2407bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasastatus_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) {
2408bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip 16 bytes:
2409bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 6-byte reserved,
2410bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte data reference index,
2411bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 8-byte reserved
2412bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 16;
2413bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint16_t channelCount;
2414bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt16(offset, &channelCount)) {
2415bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2416bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2417bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip 8 bytes:
2418bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte channelCount,
2419bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte sample size,
2420bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 4-byte reserved
2421bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 8;
2422bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint16_t sampleRate;
2423bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt16(offset, &sampleRate)) {
2424bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate");
2425bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2426bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2427bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2428bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip 4 bytes:
2429bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte sampleRate,
2430bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    //  + 2-byte reserved
2431bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 4;
2432bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    return parseAC3SpecificBox(offset, sampleRate);
2433bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa}
2434bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2435bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasastatus_t MPEG4Extractor::parseAC3SpecificBox(
2436bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        off64_t offset, uint16_t sampleRate) {
2437bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint32_t size;
2438bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // + 4-byte size
2439bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // + 4-byte type
2440bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // + 3-byte payload
2441bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    const uint32_t kAC3SpecificBoxSize = 11;
2442bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt32(offset, &size) || size < kAC3SpecificBoxSize) {
2443bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read specific box size");
2444bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2445bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2446bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2447bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 4;
2448bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint32_t type;
2449bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'a', 'c', '3')) {
2450bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3");
2451bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2452bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2453bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2454bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    offset += 4;
2455bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    const uint32_t kAC3SpecificBoxPayloadSize = 3;
2456bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    uint8_t chunk[kAC3SpecificBoxPayloadSize];
2457bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (mDataSource->readAt(offset, chunk, sizeof(chunk)) != sizeof(chunk)) {
2458bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("MPEG4Extractor: error while reading ac-3 specific block: bitstream fields");
2459bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2460bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2461bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2462bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    ABitReader br(chunk, sizeof(chunk));
2463bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
2464bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    static const unsigned sampleRateTable[] = {48000, 44100, 32000};
2465bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2466bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned fscod = br.getBits(2);
2467bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (fscod == 3) {
2468bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("Incorrect fscod (3) in AC3 header");
2469bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2470bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2471bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned boxSampleRate = sampleRateTable[fscod];
2472bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (boxSampleRate != sampleRate) {
2473bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
2474bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa            boxSampleRate, sampleRate);
2475bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2476bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2477bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2478bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned bsid = br.getBits(5);
2479bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (bsid > 8) {
2480bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
2481bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2482bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2483bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2484bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    // skip
2485bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned bsmod __unused = br.getBits(3);
2486bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2487bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned acmod = br.getBits(3);
2488bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned lfeon = br.getBits(1);
2489bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    unsigned channelCount = channelCountTable[acmod] + lfeon;
2490bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
2491bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    if (mLastTrack == NULL) {
2492bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa        return ERROR_MALFORMED;
2493bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    }
2494bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
2495bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    mLastTrack->meta->setInt32(kKeyChannelCount, channelCount);
2496bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
2497bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa    return OK;
2498bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa}
2499bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa
250005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
250105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen  ALOGV("MPEG4Extractor::parseSegmentIndex");
250205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
250305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 12) {
250405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      return -EINVAL;
250505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
250605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
250705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
250805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) {
250905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
251005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
251105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
251205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t version = flags >> 24;
251305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    flags &= 0xffffff;
251405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
251505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("sidx version %d", version);
251605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
251705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t referenceId;
251805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
251905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
252005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
252105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
252205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t timeScale;
252305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
252405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
252505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
252605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
2527e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake    if (timeScale == 0)
2528e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake        return ERROR_MALFORMED;
252905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
253005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t earliestPresentationTime;
253105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t firstOffset;
253205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
253305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 12;
253405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 12;
253505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
253605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (version == 0) {
253705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 8) {
253805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
253905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
254005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t tmp;
254105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
254205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
254305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
254405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        earliestPresentationTime = tmp;
254505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset + 4, &tmp)) {
254605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
254705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
254805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        firstOffset = tmp;
254905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 8;
255005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 8;
255105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
255205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 16) {
255305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
255405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
255505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
255605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
255705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
255805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
255905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
256005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
256105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 16;
256205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 16;
256305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
2564a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset);
256505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
256605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 4) {
256705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
256805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
256905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
257005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint16_t referenceCount;
257105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
257205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
257305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
257405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 4;
257505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 4;
257605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("refcount: %d", referenceCount);
257705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
257805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < referenceCount * 12) {
257905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
258005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
258105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
258205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t total_duration = 0;
258305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    for (unsigned int i = 0; i < referenceCount; i++) {
258405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        uint32_t d1, d2, d3;
258505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
258605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &d1) ||     // size
258705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            !mDataSource->getUInt32(offset + 4, &d2) || // duration
258805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            !mDataSource->getUInt32(offset + 8, &d3)) { // flags
258905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
259005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
259105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
259205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (d1 & 0x80000000) {
259305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGW("sub-sidx boxes not supported yet");
259405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
259505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bool sap = d3 & 0x80000000;
25963f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen        uint32_t saptype = (d3 >> 28) & 7;
25973f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen        if (!sap || (saptype != 1 && saptype != 2)) {
25983f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            // type 1 and 2 are sync samples
25993f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            ALOGW("not a stream access point, or unsupported type: %08x", d3);
260005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
260105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        total_duration += d2;
260205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 12;
260305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
260405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        SidxEntry se;
260505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        se.mSize = d1 & 0x7fffffff;
260605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        se.mDurationUs = 1000000LL * d2 / timeScale;
260705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mSidxEntries.add(se);
260805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
260905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2610c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    uint64_t sidxDuration = total_duration * 1000000 / timeScale;
261105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2612f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
2613f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
2614f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
261505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t metaDuration;
261605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
2617c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        mLastTrack->meta->setInt64(kKeyDuration, sidxDuration);
261805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
261905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
262005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
262105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
26228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) {
26238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (size < 8) {
26248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t count;
26288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 4, &count)) {
26298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (mMetaKeyMap.size() > 0) {
26338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        ALOGW("'keys' atom seen again, discarding existing entries");
26348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        mMetaKeyMap.clear();
26358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    off64_t keyOffset = offset + 8;
26388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    off64_t stopOffset = offset + size;
26398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    for (size_t i = 1; i <= count; i++) {
26408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (keyOffset + 8 > stopOffset) {
26418cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t keySize;
26458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(keyOffset, &keySize)
26468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || keySize < 8
26478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || keyOffset + keySize > stopOffset) {
26488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t type;
26528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(keyOffset + 4, &type)
26538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                || type != FOURCC('m', 'd', 't', 'a')) {
26548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keySize -= 8;
26588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keyOffset += 8;
26598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        sp<ABuffer> keyData = new ABuffer(keySize);
26618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (keyData->data() == NULL) {
26628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (mDataSource->readAt(
26658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang                keyOffset, keyData->data(), keySize) < (ssize_t) keySize) {
26668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
26678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
26688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        AString key((const char *)keyData->data(), keySize);
26708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        mMetaKeyMap.add(i, key);
26718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        keyOffset += keySize;
26738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return OK;
26758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
26768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
26778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal(
26788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        int32_t keyId, off64_t offset, size_t size) {
26798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    ssize_t index = mMetaKeyMap.indexOfKey(keyId);
26808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (index < 0) {
26818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // corresponding key is not present, ignore
26828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
268405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
26858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (size <= 16) {
26868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t dataSize;
26898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset, &dataSize)
26908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || dataSize > size || dataSize <= 16) {
26918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t atomFourCC;
26948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
26958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || atomFourCC != FOURCC('d', 'a', 't', 'a')) {
26968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
26978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
26988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    uint32_t dataType;
26998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (!mDataSource->getUInt32(offset + 8, &dataType)
27008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            || ((dataType & 0xff000000) != 0)) {
27018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // not well-known type
27028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        return ERROR_MALFORMED;
27038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
27048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
27058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    dataSize -= 16;
27068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    offset += 16;
27078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
27088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    if (dataType == 23 && dataSize >= 4) {
27098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // BE Float32
27108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        uint32_t val;
27118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!mDataSource->getUInt32(offset, &val)) {
27128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            return ERROR_MALFORMED;
27138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
27148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
27158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang            mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val);
27168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        }
27174dbff11975e737482537e1636051690188f3fbc4Praveen Chavan    } else if (dataType == 67 && dataSize >= 4) {
27184dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        // BE signed int32
27194dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        uint32_t val;
27204dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        if (!mDataSource->getUInt32(offset, &val)) {
27214dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            return ERROR_MALFORMED;
27224dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        }
27234dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
27244dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            mFileMetaData->setInt32(kKeyTemporalLayerCount, val);
27254dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        }
27268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    } else {
27278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        // add more keys if needed
27288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang        ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
27298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    }
27308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang
27318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang    return OK;
27328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang}
273305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
2734ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader(
2735c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, off64_t data_size) {
2736ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (data_size < 4) {
2737ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
2738ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2739ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2740ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t version;
2741ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(data_offset, &version, 1) < 1) {
2742ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
2743ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2744ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2745ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t dynSize = (version == 1) ? 36 : 24;
2746ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2747ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t buffer[36 + 60];
2748ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2749c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    if (data_size != (off64_t)dynSize + 60) {
2750ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
2751ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2752ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2753ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(
2754ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                data_offset, buffer, data_size) < (ssize_t)data_size) {
2755ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
2756ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2757ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2758b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    uint64_t ctime __unused, mtime __unused, duration __unused;
2759ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t id;
2760ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2761ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (version == 1) {
2762ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U64_AT(&buffer[4]);
2763ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U64_AT(&buffer[12]);
2764ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[20]);
2765ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U64_AT(&buffer[28]);
276604022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen    } else if (version == 0) {
2767ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U32_AT(&buffer[4]);
2768ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U32_AT(&buffer[8]);
2769ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[12]);
2770ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U32_AT(&buffer[20]);
277104022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen    } else {
277204022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen        return ERROR_UNSUPPORTED;
2773ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2774ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2775f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
2776f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
2777f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
2778ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    mLastTrack->meta->setInt32(kKeyTrackID, id);
2779ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2780ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t matrixOffset = dynSize + 16;
2781ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a00 = U32_AT(&buffer[matrixOffset]);
2782ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
2783ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
2784ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
2785ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2786ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0
2787b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
2788b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
2789b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe
2790df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("x' = %.2f * x + %.2f * y + %.2f",
2791ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
2792df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("y' = %.2f * x + %.2f * y + %.2f",
2793ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
2794ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif
2795ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2796ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t rotationDegrees;
2797ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2798ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    static const int32_t kFixedOne = 0x10000;
2799ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
2800ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        // Identity, no rotation
2801ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
2802ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
2803ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 90;
2804ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
2805ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 270;
2806ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
2807ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 180;
2808ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
28095ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("We only support 0,90,180,270 degree rotation matrices");
2810ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
2811ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2812ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2813ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (rotationDegrees != 0) {
2814ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
2815ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
2816ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2817b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    // Handle presentation display size, which could be different
2818b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    // from the image size indicated by kKeyWidth and kKeyHeight.
2819ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t width = U32_AT(&buffer[dynSize + 52]);
2820ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t height = U32_AT(&buffer[dynSize + 56]);
2821b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
2822b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
2823ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2824ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    return OK;
2825ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber}
2826ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
2827fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
2828d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia    if (size == 0) {
2829d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia        return OK;
2830d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia    }
2831d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia
2832c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich    if (size < 4 || size == SIZE_MAX) {
283372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_MALFORMED;
283472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
283572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
28368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
28378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (buffer == NULL) {
28388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
28398da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
284072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (mDataSource->readAt(
284172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                offset, buffer, size) != (ssize_t)size) {
284272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        delete[] buffer;
284372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        buffer = NULL;
284472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
284572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_IO;
284672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
284772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
284872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t flags = U32_AT(buffer);
284972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
285072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t metadataKey = 0;
28515d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen    char chunk[5];
28525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen    MakeFourCCString(mPath[4], chunk);
2853ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("meta: %s @ %lld", chunk, (long long)offset);
28542d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer    switch ((int32_t)mPath[4]) {
285572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'a', 'l', 'b'):
285672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
285772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbum;
285872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
285972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
286072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'A', 'R', 'T'):
286172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
286272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyArtist;
286372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
286472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
286566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        case FOURCC('a', 'A', 'R', 'T'):
286666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        {
286766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            metadataKey = kKeyAlbumArtist;
286866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            break;
286966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        }
287072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'd', 'a', 'y'):
287172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
287272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyYear;
287372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
287472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
287572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'n', 'a', 'm'):
287672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
287772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyTitle;
287872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
287972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
288072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'w', 'r', 't'):
288172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
288272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyWriter;
288372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
288472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
288572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('c', 'o', 'v', 'r'):
288672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
288772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbumArt;
288872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
288972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
289072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('g', 'n', 'r', 'e'):
289172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
289272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyGenre;
289372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
289472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
289526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC(0xa9, 'g', 'e', 'n'):
289626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
289726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            metadataKey = kKeyGenre;
289826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
289926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
290011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        case FOURCC('c', 'p', 'i', 'l'):
290111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        {
290211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            if (size == 9 && flags == 21) {
290311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                char tmp[16];
290411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                sprintf(tmp, "%d",
290511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                        (int)buffer[size - 1]);
290611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen
290711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen                mFileMetaData->setCString(kKeyCompilation, tmp);
290811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            }
290911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen            break;
291011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        }
291172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('t', 'r', 'k', 'n'):
291272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
291372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (size == 16 && flags == 0) {
291472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char tmp[16];
2915afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTrack = (uint16_t*)&buffer[10];
2916afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
2917afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
291872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
291972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
292072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
292172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
292272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
292326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC('d', 'i', 's', 'k'):
292426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
2925afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik            if ((size == 14 || size == 16) && flags == 0) {
292626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                char tmp[16];
2927afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pDisc = (uint16_t*)&buffer[10];
2928afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
2929afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik                sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
293026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
293126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(kKeyDiscNumber, tmp);
293226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            }
293326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
293426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
29355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        case FOURCC('-', '-', '-', '-'):
29365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        {
29375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            buffer[size] = '\0';
29385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            switch (mPath[5]) {
29395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('m', 'e', 'a', 'n'):
29405d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentMean.setTo((const char *)buffer + 4);
29415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
29425d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('n', 'a', 'm', 'e'):
29435d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentName.setTo((const char *)buffer + 4);
29445d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
29455d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                case FOURCC('d', 'a', 't', 'a'):
29465cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                    if (size < 8) {
29475cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        delete[] buffer;
29485cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        buffer = NULL;
29495cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        ALOGE("b/24346430");
29505cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                        return ERROR_MALFORMED;
29515cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia                    }
29525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    mLastCommentData.setTo((const char *)buffer + 8);
29535d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                    break;
29545d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            }
29558c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
29568c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // Once we have a set of mean/name/data info, go ahead and process
29578c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // it to see if its something we are interested in.  Whether or not
29588c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // were are interested in the specific tag, make sure to clear out
29598c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // the set so we can be ready to process another tuple should one
29608c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            // show up later in the file.
29618c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman            if ((mLastCommentMean.length() != 0) &&
29628c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                (mLastCommentName.length() != 0) &&
29638c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                (mLastCommentData.length() != 0)) {
29648c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
29658c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                if (mLastCommentMean == "com.apple.iTunes"
29668c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        && mLastCommentName == "iTunSMPB") {
29678c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    int32_t delay, padding;
29688c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    if (sscanf(mLastCommentData,
29698c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                               " %*x %x %x %*x", &delay, &padding) == 2) {
2970a0721999eccd22d900eb6dec7e48f835f28ce999Marco Nelissen                        if (mLastTrack == NULL) {
2971a0721999eccd22d900eb6dec7e48f835f28ce999Marco Nelissen                            delete[] buffer;
2972f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake                            return ERROR_MALFORMED;
2973a0721999eccd22d900eb6dec7e48f835f28ce999Marco Nelissen                        }
2974f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
29758c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
29768c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                        mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
29778c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman                    }
29785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                }
29798c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman
29805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentMean.clear();
29815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentName.clear();
29825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen                mLastCommentData.clear();
29835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            }
29845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen            break;
29855d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen        }
298626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
298772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        default:
298872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
298972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
299072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
2991328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
299272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        if (metadataKey == kKeyAlbumArt) {
299372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setData(
299472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    kKeyAlbumArt, MetaData::TYPE_NONE,
299572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    buffer + 8, size - 8);
299672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else if (metadataKey == kKeyGenre) {
299772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (flags == 0) {
299826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // uint8_t genre code, iTunes genre codes are
299926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // the standard id3 codes, except they start
300026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // at 1 instead of 0 (e.g. Pop is 14, not 13)
300126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // We use standard id3 numbering, so subtract 1.
300226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                int genrecode = (int)buffer[size - 1];
300326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                genrecode--;
300426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                if (genrecode < 0) {
300526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                    genrecode = 255; // reserved for 'unknown genre'
300626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                }
300772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char genre[10];
300826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                sprintf(genre, "%d", genrecode);
300972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
301072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(metadataKey, genre);
301126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            } else if (flags == 1) {
301226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // custom genre string
301326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                buffer[size] = '\0';
301426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
301526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(
301626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                        metadataKey, (const char *)buffer + 8);
301772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
301872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else {
301972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            buffer[size] = '\0';
302072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
302172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(
302272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    metadataKey, (const char *)buffer + 8);
302372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
302472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
302572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
302672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    delete[] buffer;
302772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    buffer = NULL;
302872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
302972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return OK;
303072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
303172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
303258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
303358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
303458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_MALFORMED;
303558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
303658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
303758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
303858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (buffer == NULL) {
303958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_MALFORMED;
304058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
304158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
304258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        delete[] buffer;
304358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        buffer = NULL;
304458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
304558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        return ERROR_IO;
304658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
304758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
304858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    int32_t type = U32_AT(&buffer[0]);
304958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
305051a0ff56f49faf1a19281f6d786fe18bf84794c6Hangyu Kuang            || (type == FOURCC('n', 'c', 'l', 'c') && size >= 10)) {
305158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t primaries = U16_AT(&buffer[4]);
305258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t transfer = U16_AT(&buffer[6]);
305358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t coeffs = U16_AT(&buffer[8]);
305458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);
305558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
305658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorAspects aspects;
305758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorUtils::convertIsoColorAspectsToCodecAspects(
305858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                primaries, transfer, coeffs, fullRange, aspects);
305958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
306058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        // only store the first color specification
306158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) {
306258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries);
306358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer);
306458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
306558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange);
306658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        }
306758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
306858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
306958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    delete[] buffer;
307058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    buffer = NULL;
307158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
307258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    return OK;
307358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar}
307458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
3075fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
30765cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake    if (size < 4 || size == SIZE_MAX) {
3077fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        return ERROR_MALFORMED;
3078fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3079fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
30805cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
30818da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (buffer == NULL) {
30828da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
30838da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
3084fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    if (mDataSource->readAt(
3085fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                offset, buffer, size) != (ssize_t)size) {
3086fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        delete[] buffer;
3087fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        buffer = NULL;
3088fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3089fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        return ERROR_IO;
3090fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3091fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3092fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    uint32_t metadataKey = 0;
3093fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    switch (mPath[depth]) {
3094fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('t', 'i', 't', 'l'):
3095fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3096fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyTitle;
3097fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3098fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3099fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('p', 'e', 'r', 'f'):
3100fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3101fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyArtist;
3102fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3103fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3104fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'u', 't', 'h'):
3105fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3106fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyWriter;
3107fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3108fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3109fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('g', 'n', 'r', 'e'):
3110fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3111fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyGenre;
3112fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3113fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3114fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('a', 'l', 'b', 'm'):
3115fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
3116fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (buffer[size - 1] != '\0') {
3117fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              char tmp[4];
3118fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              sprintf(tmp, "%u", buffer[size - 1]);
3119fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3120fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé              mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
3121fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3122fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3123fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            metadataKey = kKeyAlbum;
3124fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3125fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3126fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        case FOURCC('y', 'r', 'r', 'c'):
3127fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        {
31286ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang            if (size < 6) {
31296ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang                delete[] buffer;
31306ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang                buffer = NULL;
31316ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang                ALOGE("b/62133227");
31326ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang                android_errorWriteLog(0x534e4554, "62133227");
31336ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang                return ERROR_MALFORMED;
31346ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang            }
3135fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            char tmp[5];
3136fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            uint16_t year = U16_AT(&buffer[4]);
3137fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3138fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (year < 10000) {
3139fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                sprintf(tmp, "%u", year);
3140fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3141fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                mFileMetaData->setCString(kKeyYear, tmp);
3142fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3143fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3144fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3145fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3146fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        default:
3147fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            break;
3148fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3149fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3150fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    if (metadataKey > 0) {
3151fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        bool isUTF8 = true; // Common case
3152fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        char16_t *framedata = NULL;
3153fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        int len16 = 0; // Number of UTF-16 characters
3154fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3155fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
31569458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake        if (size < 6) {
31576ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang            delete[] buffer;
31586ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang            buffer = NULL;
31599458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake            return ERROR_MALFORMED;
31609458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake        }
31619458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake
3162fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        if (size - 6 >= 4) {
3163fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
3164fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            framedata = (char16_t *)(buffer + 6);
3165fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (0xfffe == *framedata) {
3166fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // endianness marker (BOM) doesn't match host endianness
3167fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                for (int i = 0; i < len16; i++) {
3168fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                    framedata[i] = bswap_16(framedata[i]);
3169fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                }
3170fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // BOM is now swapped to 0xfeff, we will execute next block too
3171fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3172fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3173fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            if (0xfeff == *framedata) {
3174fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                // Remove the BOM
3175fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                framedata++;
3176fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                len16--;
3177fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé                isUTF8 = false;
3178fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            }
3179fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // else normal non-zero-length UTF-8 string
3180fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // we can't handle UTF-16 without BOM as there is no other
3181fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // indication of encoding.
3182fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3183fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3184fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        if (isUTF8) {
31855cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake            buffer[size] = 0;
3186fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            mFileMetaData->setCString(metadataKey, (const char *)buffer + 6);
3187fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        } else {
3188fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            // Convert from UTF-16 string to UTF-8 string.
3189fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            String8 tmpUTF8str(framedata, len16);
3190fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé            mFileMetaData->setCString(metadataKey, tmpUTF8str.string());
3191fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé        }
3192fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    }
3193fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3194fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    delete[] buffer;
3195fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    buffer = NULL;
3196fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3197fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé    return OK;
3198fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé}
3199fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé
3200328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
3201328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    ID3 id3(mDataSource, true /* ignorev1 */, offset);
3202328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3203328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (id3.isValid()) {
3204328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        struct Map {
3205328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            int key;
3206328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            const char *tag1;
3207328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            const char *tag2;
3208328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        };
3209328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        static const Map kMap[] = {
3210328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAlbum, "TALB", "TAL" },
3211328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyArtist, "TPE1", "TP1" },
3212328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAlbumArtist, "TPE2", "TP2" },
3213328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyComposer, "TCOM", "TCM" },
3214328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyGenre, "TCON", "TCO" },
3215328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyTitle, "TIT2", "TT2" },
3216328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyYear, "TYE", "TYER" },
3217328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyAuthor, "TXT", "TEXT" },
3218328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyCDTrackNumber, "TRK", "TRCK" },
3219328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyDiscNumber, "TPA", "TPOS" },
3220328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            { kKeyCompilation, "TCP", "TCMP" },
3221328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        };
3222328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
3223328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3224328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        for (size_t i = 0; i < kNumMapEntries; ++i) {
3225328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            if (!mFileMetaData->hasData(kMap[i].key)) {
3226328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
3227328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                if (it->done()) {
3228328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    delete it;
3229328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    it = new ID3::Iterator(id3, kMap[i].tag2);
3230328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                }
3231328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3232328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                if (it->done()) {
3233328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    delete it;
3234328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                    continue;
3235328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                }
3236328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3237328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                String8 s;
3238328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                it->getString(&s);
3239328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                delete it;
3240328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3241328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé                mFileMetaData->setCString(kMap[i].key, s);
3242328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            }
3243328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
3244328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3245328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        size_t dataSize;
3246328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        String8 mime;
3247328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        const void *data = id3.getAlbumArt(&dataSize, &mime);
3248328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3249328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        if (data) {
3250328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
3251328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé            mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
3252328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        }
3253328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    }
3254328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé}
3255328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
3256b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) {
325720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
325820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
3259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return NULL;
326020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
326120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
326220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
326320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
326420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
3265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return NULL;
326620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
326720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
326820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
326920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
327020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
327120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3272371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
3273371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
3274371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
3275371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
3276c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3277c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    Trex *trex = NULL;
3278c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    int32_t trackId;
3279c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    if (track->meta->findInt32(kKeyTrackID, &trackId)) {
3280c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        for (size_t i = 0; i < mTrex.size(); i++) {
3281949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen            Trex *t = &mTrex.editItemAt(i);
3282c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            if (t->track_ID == (uint32_t) trackId) {
3283c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                trex = t;
3284c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen                break;
3285c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            }
3286c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
32870386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    } else {
32880386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        ALOGE("b/21657957");
32890386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        return NULL;
3290c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    }
3291c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3292a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("getTrack called, pssh: %zu", mPssh.size());
3293ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3294a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    const char *mime;
3295a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    if (!track->meta->findCString(kKeyMIMEType, &mime)) {
3296a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        return NULL;
3297a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    }
3298a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3299a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3300a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        uint32_t type;
3301a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const void *data;
3302a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        size_t size;
3303a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) {
3304a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3305a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3306a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3307a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const uint8_t *ptr = (const uint8_t *)data;
3308a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3309a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
3310a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3311a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3312a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
3313a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        uint32_t type;
3314a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const void *data;
3315a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        size_t size;
3316a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) {
3317a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3318a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3319a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3320a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        const uint8_t *ptr = (const uint8_t *)data;
3321a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3322a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        if (size < 22 || ptr[0] != 1) {  // configurationVersion == 1
3323a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia            return NULL;
3324a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        }
3325a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia    }
3326a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia
3327ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    sp<MPEG4Source> source =  new MPEG4Source(this,
332805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            track->meta, mDataSource, track->timescale, track->sampleTable,
3329c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mSidxEntries, trex, mMoofOffset);
3330ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    if (source->init() != OK) {
3331ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia        return NULL;
3332ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    }
3333ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    return source;
333420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
333520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3336bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static
3337bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) {
3338bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const char *mime;
3339bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
3340bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3341bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    uint32_t type;
3342bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const void *data;
3343bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    size_t size;
3344bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
3345bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
3346bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeAVCC) {
3347bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
3348bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
33493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
33503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!track->meta->findData(kKeyHVCC, &type, &data, &size)
33513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                    || type != kTypeHVCC) {
33523b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            return ERROR_MALFORMED;
33533b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
3354bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
3355ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar            || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
3356bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
3357bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
3358bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeESDS) {
3359bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
3360bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
3361bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    }
3362bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3363ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih    if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
3364169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        // Make sure we have all the metadata we need.
3365ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih        ALOGE("stbl atom missing/invalid.");
3366169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        return ERROR_MALFORMED;
3367169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    }
3368169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
33692e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang    if (track->timescale == 0) {
33702e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang        ALOGE("timescale invalid.");
33712e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang        return ERROR_MALFORMED;
33722e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang    }
33732e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang
3374bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    return OK;
3375bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber}
3376bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
3377f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum {
3378f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_NONE             = -1,
3379f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_NULL_OBJECT      = 0,
3380f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_MAIN         = 1, /**< Main profile                              */
3381f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_AAC_LC           = 2,   /**< Low Complexity object                     */
3382f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SSR          = 3,
3383f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_LTP          = 4,
3384f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_SBR              = 5,
3385f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SCAL         = 6,
3386f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_TWIN_VQ          = 7,
3387f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_CELP             = 8,
3388f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_HVXC             = 9,
3389f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_10          = 10, /**< (reserved)                                */
3390f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_11          = 11, /**< (reserved)                                */
3391f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_TTSI             = 12, /**< TTSI Object                               */
3392f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MAIN_SYNTH       = 13, /**< Main Synthetic object                     */
3393f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_WAV_TAB_SYNTH    = 14, /**< Wavetable Synthesis object                */
3394f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_GEN_MIDI         = 15, /**< General MIDI object                       */
3395f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
3396f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_LC        = 17,   /**< Error Resilient(ER) AAC Low Complexity    */
3397f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_18          = 18, /**< (reserved)                                */
3398f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_AAC_LTP       = 19, /**< Error Resilient(ER) AAC LTP object        */
3399f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_SCAL      = 20,   /**< Error Resilient(ER) AAC Scalable object   */
3400f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_TWIN_VQ       = 21, /**< Error Resilient(ER) TwinVQ object         */
3401f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_BSAC          = 22,   /**< Error Resilient(ER) BSAC object           */
3402f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ER_AAC_LD        = 23,   /**< Error Resilient(ER) AAC LowDelay object   */
3403f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_CELP          = 24, /**< Error Resilient(ER) CELP object           */
3404f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_HVXC          = 25, /**< Error Resilient(ER) HVXC object           */
3405f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_HILN          = 26, /**< Error Resilient(ER) HILN object           */
3406f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_PARA          = 27, /**< Error Resilient(ER) Parametric object     */
3407f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_28          = 28, /**< might become SSC                          */
3408f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_PS               = 29,   /**< PS, Parametric Stereo (includes SBR)      */
3409f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MPEGS            = 30, /**< MPEG Surround                             */
3410f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3411f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    AOT_ESCAPE           = 31,   /**< Signal AOT uses more than 5 bits          */
3412f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3413f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L1      = 32, /**< MPEG-Layer1 in mp4                        */
3414f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L2      = 33, /**< MPEG-Layer2 in mp4                        */
3415f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_MP3ONMP4_L3      = 34, /**< MPEG-Layer3 in mp4                        */
3416f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_35          = 35, /**< might become DST                          */
3417f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD_36          = 36, /**< might become ALS                          */
3418f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_AAC_SLS          = 37, /**< AAC + SLS                                 */
3419f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_SLS              = 38, /**< SLS                                       */
3420f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_ER_AAC_ELD       = 39, /**< AAC Enhanced Low Delay                    */
3421f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3422f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_USAC             = 42, /**< USAC                                      */
3423f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_SAOC             = 43, /**< SAOC                                      */
3424f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_LD_MPEGS         = 44, /**< Low Delay MPEG Surround                   */
3425f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3426f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    //AOT_RSVD50           = 50,  /**< Interim AOT for Rsvd50                   */
3427f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE;
3428f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3429ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
3430ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        const void *esds_data, size_t esds_size) {
3431ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    ESDS esds(esds_data, esds_size);
343281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
343381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    uint8_t objectTypeIndication;
343481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
343581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return ERROR_MALFORMED;
343681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
343781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
343881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (objectTypeIndication == 0xe1) {
343981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // This isn't MPEG4 audio at all, it's QCELP 14k...
3440f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        if (mLastTrack == NULL)
3441f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake            return ERROR_MALFORMED;
3442f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
344381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
344481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return OK;
344581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
344681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
3447633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong    if (objectTypeIndication  == 0x6b) {
3448633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // The media subtype is MP3 audio
3449633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // Our software MP3 audio decoder may not be able to handle
3450633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
345129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("MP3 track in MP4/3GPP file is not supported");
3452633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong        return ERROR_UNSUPPORTED;
3453633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong    }
3454633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong
3455ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    const uint8_t *csd;
3456ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    size_t csd_size;
3457ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (esds.getCodecSpecificInfo(
3458ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                (const void **)&csd, &csd_size) != OK) {
3459ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
3460ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3461ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3462b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    if (kUseHexDump) {
3463ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        printf("ESD of size %zu\n", csd_size);
3464b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        hexdump(csd, csd_size);
3465b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    }
3466ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3467a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    if (csd_size == 0) {
3468a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // There's no further information, i.e. no codec specific data
3469a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // Let's assume that the information provided in the mpeg4 headers
3470a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // is accurate and hope for the best.
3471a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
3472a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        return OK;
3473a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    }
3474a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
3475ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (csd_size < 2) {
3476ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
3477ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3478ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
347900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    static uint32_t kSamplingRate[] = {
348000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
348100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        16000, 12000, 11025, 8000, 7350
348200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    };
348300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent
3484aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    ABitReader br(csd, csd_size);
3485aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    uint32_t objectType = br.getBits(5);
3486ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3487aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (objectType == 31) {  // AAC-ELD => additional 6 bits
3488aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        objectType = 32 + br.getBits(6);
3489ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3490ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3491f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
3492f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
3493f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
3494db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    //keep AOT type
3495db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
3496db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
3497aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    uint32_t freqIndex = br.getBits(4);
3498aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
3499ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t sampleRate = 0;
3500ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t numChannels = 0;
3501ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (freqIndex == 15) {
35028e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
3503aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        sampleRate = br.getBits(24);
3504aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        numChannels = br.getBits(4);
3505ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    } else {
35068e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3507595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen        numChannels = br.getBits(4);
350800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent
350900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        if (freqIndex == 13 || freqIndex == 14) {
351000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            return ERROR_MALFORMED;
3511ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        }
3512ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
351300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        sampleRate = kSamplingRate[freqIndex];
351400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent    }
3515595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen
3516f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
35178e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen        if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
351800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        uint32_t extFreqIndex = br.getBits(4);
3519b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        int32_t extSampleRate __unused;
352000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        if (extFreqIndex == 15) {
352100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            if (csd_size < 8) {
3522595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen                return ERROR_MALFORMED;
3523595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen            }
35248e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
352500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            extSampleRate = br.getBits(24);
352600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        } else {
352700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            if (extFreqIndex == 13 || extFreqIndex == 14) {
352800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent                return ERROR_MALFORMED;
352900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            }
353000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent            extSampleRate = kSamplingRate[extFreqIndex];
3531595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen        }
353200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        //TODO: save the extension sampling rate value in meta data =>
353300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent        //      mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
3534ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3535ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3536f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    switch (numChannels) {
3537f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
3538f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 0:
3539f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 1:// FC
3540f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 2:// FL FR
3541f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 3:// FC, FL FR
3542f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 4:// FC, FL FR, RC
3543f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 5:// FC, FL FR, SL SR
3544f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 6:// FC, FL FR, SL SR, LFE
3545f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            //numChannels already contains the right value
3546f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3547f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 11:// FC, FL FR, SL SR, RC, LFE
3548f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            numChannels = 7;
3549f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3550f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 7: // FC, FCL FCR, FL FR, SL SR, LFE
3551f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 12:// FC, FL  FR,  SL SR, RL RR, LFE
3552f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        case 14:// FC, FL  FR,  SL SR, LFE, FHL FHR
3553f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            numChannels = 8;
3554f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            break;
3555f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        default:
3556f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            return ERROR_UNSUPPORTED;
3557f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    }
3558f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3559f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    {
3560f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        if (objectType == AOT_SBR || objectType == AOT_PS) {
35618e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3562f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            objectType = br.getBits(5);
3563f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3564f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            if (objectType == AOT_ESCAPE) {
35658e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
3566f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType = 32 + br.getBits(6);
3567f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3568f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        }
3569f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
3570f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
3571f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                objectType == AOT_ER_BSAC) {
35728e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen            if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
3573b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe            const int32_t frameLengthFlag __unused = br.getBits(1);
3574f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3575f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            const int32_t dependsOnCoreCoder = br.getBits(1);
3576f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3577f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            if (dependsOnCoreCoder ) {
35788e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
3579b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t coreCoderDelay __unused = br.getBits(14);
3580f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3581f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
358245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            int32_t extensionFlag = -1;
358345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            if (br.numBitsLeft() > 0) {
358445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                extensionFlag = br.getBits(1);
358545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            } else {
358645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                switch (objectType) {
358745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                // 14496-3 4.5.1.1 extensionFlag
358845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_AAC_LC:
358945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    extensionFlag = 0;
359045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
359145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_LC:
359245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_SCAL:
359345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_BSAC:
359445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                case AOT_ER_AAC_LD:
359545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    extensionFlag = 1;
359645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
359745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                default:
35988e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    return ERROR_MALFORMED;
359945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                    break;
360045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                }
360145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                ALOGW("csd missing extension flag; assuming %d for object type %u.",
360245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih                        extensionFlag, objectType);
360345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            }
3604f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
360545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih            if (numChannels == 0) {
3606f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int32_t channelsEffectiveNum = 0;
3607f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int32_t channelsNum = 0;
36088e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 32) {
36098e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    return ERROR_MALFORMED;
36108e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                }
3611b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t ElementInstanceTag __unused = br.getBits(4);
3612b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t Profile __unused = br.getBits(2);
3613b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
3614f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumFrontChannelElements = br.getBits(4);
3615f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumSideChannelElements = br.getBits(4);
3616f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumBackChannelElements = br.getBits(4);
3617f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t NumLfeChannelElements = br.getBits(2);
3618b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t NumAssocDataElements __unused = br.getBits(3);
3619b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                const int32_t NumValidCcElements __unused = br.getBits(4);
3620f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3621f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t MonoMixdownPresent = br.getBits(1);
36228e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen
3623f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (MonoMixdownPresent != 0) {
36248e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3625b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
3626f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3627f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
36288e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3629f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t StereoMixdownPresent = br.getBits(1);
3630f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (StereoMixdownPresent != 0) {
36318e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3632b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
3633f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3634f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
36358e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
3636f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                const int32_t MatrixMixdownIndexPresent = br.getBits(1);
3637f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                if (MatrixMixdownIndexPresent != 0) {
36388e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
3639b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t MatrixMixdownIndex __unused = br.getBits(2);
3640b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t PseudoSurroundEnable __unused = br.getBits(1);
3641f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3642f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3643f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                int i;
3644f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumFrontChannelElements; i++) {
36458e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3646f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t FrontElementIsCpe = br.getBits(1);
3647b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t FrontElementTagSelect __unused = br.getBits(4);
3648f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += FrontElementIsCpe ? 2 : 1;
3649f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3650f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3651f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumSideChannelElements; i++) {
36528e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3653f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t SideElementIsCpe = br.getBits(1);
3654b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t SideElementTagSelect __unused = br.getBits(4);
3655f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += SideElementIsCpe ? 2 : 1;
3656f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3657f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3658f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumBackChannelElements; i++) {
36598e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
3660f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    const int32_t BackElementIsCpe = br.getBits(1);
3661b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t BackElementTagSelect __unused = br.getBits(4);
3662f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += BackElementIsCpe ? 2 : 1;
3663f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3664f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                channelsEffectiveNum = channelsNum;
3665f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3666f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                for (i=0; i < NumLfeChannelElements; i++) {
36678e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen                    if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
3668b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe                    const int32_t LfeElementTagSelect __unused = br.getBits(4);
3669f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                    channelsNum += 1;
3670f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                }
3671f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
3672f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
3673f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi                numChannels = channelsNum;
3674f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi            }
3675f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi        }
3676f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi    }
3677f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi
3678ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (numChannels == 0) {
3679ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_UNSUPPORTED;
3680ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3681ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3682f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake    if (mLastTrack == NULL)
3683f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake        return ERROR_MALFORMED;
3684f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake
3685ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevSampleRate;
3686ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
3687ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3688ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevSampleRate != sampleRate) {
36893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("mpeg4 audio sample rate different from previous setting. "
3690ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevSampleRate, sampleRate);
3691ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3692ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3693ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
3694ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3695ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevChannelCount;
3696ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
3697ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3698ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevChannelCount != numChannels) {
36993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("mpeg4 audio channel count different from previous setting. "
3700ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevChannelCount, numChannels);
3701ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
3702ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3703ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
3704ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
3705ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    return OK;
3706ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber}
3707ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
370820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
370920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
371020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source(
3711942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen        const sp<MPEG4Extractor> &owner,
371220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const sp<MetaData> &format,
3713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &dataSource,
371448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        int32_t timeScale,
371505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const sp<SampleTable> &sampleTable,
371605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        Vector<SidxEntry> &sidx,
3717c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        const Trex *trex,
371805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t firstMoofOffset)
3719942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen    : mOwner(owner),
3720942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen      mFormat(format),
372120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDataSource(dataSource),
372248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber      mTimescale(timeScale),
372320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleTable(sampleTable),
372420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mCurrentSampleIndex(0),
372505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentFragmentIndex(0),
372605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mSegments(sidx),
3727c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen      mTrex(trex),
372805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mFirstMoofOffset(firstMoofOffset),
372905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentMoofOffset(firstMoofOffset),
3730ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia      mNextMoofOffset(-1),
373105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen      mCurrentTime(0),
3732ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoAllocSize(0),
3733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoSizes(NULL),
3734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoOffsetsAllocSize(0),
3735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen      mCurrentSampleInfoOffsets(NULL),
373620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mIsAVC(false),
37373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar      mIsHEVC(false),
37386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber      mNALLengthSize(0),
373920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStarted(false),
374020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mGroup(NULL),
374120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mBuffer(NULL),
3742dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber      mWantsNALFragments(false),
37430024245e134467d120b40099da16c467dc365e76Andreas Huber      mSrcBuffer(NULL) {
3744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
3745c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
3746c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
3747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
374848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    mDefaultIVSize = 0;
3749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
3750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t keytype;
3751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    const void *key;
3752ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    size_t keysize;
3753ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) {
3754ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        CHECK(keysize <= 16);
3755ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memset(mCryptoKey, 0, 16);
3756ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memcpy(mCryptoKey, key, keysize);
3757ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
3758ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
375920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
376020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = mFormat->findCString(kKeyMIMEType, &mime);
3761dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(success);
376220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
376318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
37643b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
37656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    if (mIsAVC) {
37676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        uint32_t type;
37686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const void *data;
37696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t size;
37706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
37716064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const uint8_t *ptr = (const uint8_t *)data;
37736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(size >= 7);
3775ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
37766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
37776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        // The number of bytes used to encode the length of a NAL unit.
37786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        mNALLengthSize = 1 + (ptr[4] & 3);
37793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (mIsHEVC) {
37803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        uint32_t type;
37813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const void *data;
37823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t size;
37833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        CHECK(format->findData(kKeyHVCC, &type, &data, &size));
37843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
37853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
37863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3787a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia        CHECK(size >= 22);
37883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
37893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
37903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        mNALLengthSize = 1 + (ptr[14 + 7] & 3);
37916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
379205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
379305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    CHECK(format->findInt32(kKeyTrackID, &mTrackId));
379405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
3795ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia}
3796ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia
3797ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jiastatus_t MPEG4Source::init() {
379805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mFirstMoofOffset != 0) {
379905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        off64_t offset = mFirstMoofOffset;
3800ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia        return parseChunk(&offset);
380105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
3802ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia    return OK;
380320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
380420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
380520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() {
380620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
380720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        stop();
380820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
3809ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    free(mCurrentSampleInfoSizes);
3810ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    free(mCurrentSampleInfoOffsets);
381120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
381220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
381320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) {
38147b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
38157b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
3816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(!mStarted);
381720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
381820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t val;
3819dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (params && params->findInt32(kKeyWantsNALFragments, &val)
382020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        && val != 0) {
3821dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = true;
382220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
3823dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = false;
382420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
382520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3826afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    int32_t tmp;
3827afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp));
3828afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    size_t max_size = tmp;
382920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3830afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    // A somewhat arbitrary limit that should be sufficient for 8k video frames
3831afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    // If you see the message below for a valid input stream: increase the limit
3832cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    const size_t kMaxBufferSize = 64 * 1024 * 1024;
3833cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (max_size > kMaxBufferSize) {
3834cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize);
3835cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        return ERROR_MALFORMED;
3836cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
3837cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (max_size == 0) {
3838cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        ALOGE("zero max input size");
3839afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        return ERROR_MALFORMED;
3840afd492436efc7f66b958da14659b52232efa5910Marco Nelissen    }
38410024245e134467d120b40099da16c467dc365e76Andreas Huber
3842cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize.
3843cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    const size_t kMaxBuffers = 8;
3844cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers);
3845cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    mGroup = new MediaBufferGroup(buffers, max_size);
38468da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    mSrcBuffer = new (std::nothrow) uint8_t[max_size];
38478da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    if (mSrcBuffer == NULL) {
38488da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        // file probably specified a bad max size
3849afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        delete mGroup;
3850afd492436efc7f66b958da14659b52232efa5910Marco Nelissen        mGroup = NULL;
38518da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen        return ERROR_MALFORMED;
38528da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen    }
385320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
385420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = true;
385520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
385620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
385720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
385820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
385920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() {
38607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
38617b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
3862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
386320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
386420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mBuffer != NULL) {
386520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->release();
386620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
386720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
386820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38690024245e134467d120b40099da16c467dc365e76Andreas Huber    delete[] mSrcBuffer;
38700024245e134467d120b40099da16c467dc365e76Andreas Huber    mSrcBuffer = NULL;
38710024245e134467d120b40099da16c467dc365e76Andreas Huber
387220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete mGroup;
387320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mGroup = NULL;
387420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
387520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = false;
387620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCurrentSampleIndex = 0;
387720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
387820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
387920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
388020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
388105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) {
388205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t hdr[2];
388305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
388405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_IO;
388505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
388605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t chunk_size = ntohl(hdr[0]);
388705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t chunk_type = ntohl(hdr[1]);
388805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t data_offset = *offset + 8;
388905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
389005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (chunk_size == 1) {
389105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
389205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_IO;
389305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
389405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        chunk_size = ntoh64(chunk_size);
389505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        data_offset += 8;
389605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
389705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (chunk_size < 16) {
389805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            // The smallest valid chunk is 16 bytes long in this case.
389905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
390005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
390105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (chunk_size < 8) {
390205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // The smallest valid chunk is 8 bytes long.
390305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
390405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
390605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    char chunk[5];
390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    MakeFourCCString(chunk_type, chunk);
3908ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
390905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t chunk_data_size = *offset + chunk_size - data_offset;
391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    switch(chunk_type) {
391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'r', 'a', 'f'):
391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('m', 'o', 'o', 'f'): {
391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            off64_t stop_offset = *offset + chunk_size;
391705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset = data_offset;
391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            while (*offset < stop_offset) {
391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err = parseChunk(offset);
392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (err != OK) {
392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return err;
392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
39253f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                // *offset points to the box following this moof. Find the next moof from there.
39263f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen
39273f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                while (true) {
39283f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
39292bdbb166a4063a91bab75e50170695370004feccWei Jia                        // no more box to the end of file.
39302bdbb166a4063a91bab75e50170695370004feccWei Jia                        break;
39313f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    }
39323f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    chunk_size = ntohl(hdr[0]);
39333f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    chunk_type = ntohl(hdr[1]);
3934ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    if (chunk_size == 1) {
3935ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box
3936ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // which is defined in 4.2 Object Structure.
3937ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // When chunk_size==1, 8 bytes follows as "largesize".
3938ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
3939ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                            return ERROR_IO;
3940ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        }
3941ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        chunk_size = ntoh64(chunk_size);
3942ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        if (chunk_size < 16) {
3943ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                            // The smallest valid chunk is 16 bytes long in this case.
3944ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                            return ERROR_MALFORMED;
3945ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        }
3946ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    } else if (chunk_size == 0) {
3947ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // next box extends to end of file.
3948ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    } else if (chunk_size < 8) {
3949ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        // The smallest valid chunk is 8 bytes long in this case.
3950ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        return ERROR_MALFORMED;
3951ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    }
3952ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia
39533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
39543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        mNextMoofOffset = *offset;
39553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                        break;
3956ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                    } else if (chunk_size == 0) {
3957ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                        break;
39583f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    }
39593f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    *offset += chunk_size;
39603f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                }
396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            break;
396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'f', 'h', 'd'): {
396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err;
396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return err;
396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                *offset += chunk_size;
397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                break;
397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        case FOURCC('t', 'r', 'u', 'n'): {
397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                status_t err;
397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (mLastParsedTrackId == mTrackId) {
397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        return err;
397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    }
398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                *offset += chunk_size;
398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                break;
398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
398505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
3986ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'a', 'i', 'z'): {
3987ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            status_t err;
3988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
3989ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return err;
3990ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3991ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
3992ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
3993ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
3994ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('s', 'a', 'i', 'o'): {
3995ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            status_t err;
3996ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) {
3997ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return err;
3998ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
3999ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
4000ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
4001ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4002ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4003ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        case FOURCC('m', 'd', 'a', 't'): {
4004ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // parse DRM info if present
4005ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            ALOGV("MPEG4Source::parseChunk mdat");
4006ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            // if saiz/saoi was previously observed, do something with the sampleinfos
4007ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            *offset += chunk_size;
4008ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            break;
4009ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4010ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
401105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        default: {
401205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *offset += chunk_size;
401305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            break;
401405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
401505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
401984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
402084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t offset, off64_t /* size */) {
4021ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    ALOGV("parseSampleAuxiliaryInformationSizes");
4022ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // 14496-12 8.7.12
4023ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t version;
4024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(
4025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset, &version, sizeof(version))
4026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            < (ssize_t)sizeof(version)) {
4027ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4028ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (version != 0) {
4031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_UNSUPPORTED;
4032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
4034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t flags;
4036ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt24(offset, &flags)) {
4037ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4038ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4039ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 3;
4040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (flags & 1) {
4042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        uint32_t tmp;
4043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
4044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_MALFORMED;
4045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentAuxInfoType = tmp;
4047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        offset += 4;
4048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (!mDataSource->getUInt32(offset, &tmp)) {
4049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_MALFORMED;
4050ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4051ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentAuxInfoTypeParameter = tmp;
4052ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        offset += 4;
4053ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4054ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t defsize;
4056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(offset, &defsize, 1) != 1) {
4057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_MALFORMED;
4058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mCurrentDefaultSampleInfoSize = defsize;
4060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
4061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t smplcnt;
4063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &smplcnt)) {
4064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_MALFORMED;
4065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
406648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    mCurrentSampleInfoCount = smplcnt;
4067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 4;
4068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
406948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (mCurrentDefaultSampleInfoSize != 0) {
407048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
407148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        return OK;
407248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
4073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (smplcnt > mCurrentSampleInfoAllocSize) {
4074b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        uint8_t * newPtr =  (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
4075b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        if (newPtr == NULL) {
4076b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoAllocSize, smplcnt);
4077b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen            return NO_MEMORY;
4078b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        }
4079b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen        mCurrentSampleInfoSizes = newPtr;
4080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoAllocSize = smplcnt;
4081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
4084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
4085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
4086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
408784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
408884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        off64_t offset, off64_t /* size */) {
4089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    ALOGV("parseSampleAuxiliaryInformationOffsets");
4090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // 14496-12 8.7.13
4091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t version;
4092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
4093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset++;
4096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t flags;
4098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt24(offset, &flags)) {
4099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 3;
4102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t entrycount;
4104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &entrycount)) {
4105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return ERROR_IO;
4106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    offset += 4;
4108c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (entrycount == 0) {
4109c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return OK;
4110c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
4111c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (entrycount > UINT32_MAX / 8) {
4112c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return ERROR_MALFORMED;
4113c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
4114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
4116c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
4117c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        if (newPtr == NULL) {
4118b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen            ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
4119c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia            return NO_MEMORY;
4120c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        }
4121c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        mCurrentSampleInfoOffsets = newPtr;
4122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        mCurrentSampleInfoOffsetsAllocSize = entrycount;
4123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    mCurrentSampleInfoOffsetCount = entrycount;
4125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4126c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    if (mCurrentSampleInfoOffsets == NULL) {
4127c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia        return OK;
4128c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia    }
4129c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia
4130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < entrycount; i++) {
4131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (version == 0) {
4132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint32_t tmp;
4133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (!mDataSource->getUInt32(offset, &tmp)) {
4134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
4135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
4136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mCurrentSampleInfoOffsets[i] = tmp;
4137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset += 4;
4138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        } else {
4139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            uint64_t tmp;
4140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            if (!mDataSource->getUInt64(offset, &tmp)) {
4141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
4142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
4143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            mCurrentSampleInfoOffsets[i] = tmp;
4144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            offset += 8;
4145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    // parse clear/encrypted data
4149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
4151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    drmoffset += mCurrentMoofOffset;
4153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    int ivlength;
4154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
415548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
4156529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    // only 0, 8 and 16 byte initialization vectors are supported
4157529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
4158529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        ALOGW("unsupported IV length: %d", ivlength);
4159529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        return ERROR_MALFORMED;
4160529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen    }
416148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    // read CencSampleAuxiliaryDataFormats
4162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
4163529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        if (i >= mCurrentSamples.size()) {
4164529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen            ALOGW("too few samples");
4165529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen            break;
4166529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen        }
4167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        Sample *smpl = &mCurrentSamples.editItemAt(i);
4168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memset(smpl->iv, 0, 16);
4170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) {
4171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            return ERROR_IO;
4172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4173ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4174ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        drmoffset += ivlength;
4175ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
417648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
417748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        if (smplinfosize == 0) {
417848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smplinfosize = mCurrentSampleInfoSizes[i];
4179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
418048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        if (smplinfosize > ivlength) {
418148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            uint16_t numsubsamples;
418248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
4183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen                return ERROR_IO;
4184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
4185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            drmoffset += 2;
418648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            for (size_t j = 0; j < numsubsamples; j++) {
418748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                uint16_t numclear;
418848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                uint32_t numencrypted;
418948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                if (!mDataSource->getUInt16(drmoffset, &numclear)) {
419048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                    return ERROR_IO;
419148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                }
419248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                drmoffset += 2;
419348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
419448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                    return ERROR_IO;
419548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                }
419648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                drmoffset += 4;
419748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->clearsizes.add(numclear);
419848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->encryptedsizes.add(numencrypted);
4199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen            }
420048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        } else {
420148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smpl->clearsizes.add(0);
420248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen            smpl->encryptedsizes.add(smpl->size);
4203ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        }
4204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
4205ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4206ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
4207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
4208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
4209ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
421005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
421105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
421205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 8) {
421305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
421405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
421505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
421605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
4217ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
421805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
421905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
422005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
422105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & 0xff000000) {
422205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
422305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
422405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
422505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
422605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
422705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
422805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
422905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mLastParsedTrackId != mTrackId) {
423005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // this is not the right track, skip it
423105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
423205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
423305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
423405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mFlags = flags;
423505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
423605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 8;
423705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 8;
423805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
423905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
424005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
424105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
424205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 8) {
424305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
424405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
424505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
424605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
424705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
424805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
424905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 8;
425005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 8;
425105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
425205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
425305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
425405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
425505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
425605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
425705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
425805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
425905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
426005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
426105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
426205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
426305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
426405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
426505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
426605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
426705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
426805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
426905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
427005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
427105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
427205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
427305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
427405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
427505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
427605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
427705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
427805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
427905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
428005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
428105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
428205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
428305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
428405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
428505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
428605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
428705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
428805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
428905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
429005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
429105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
429205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
429305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
429405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
429505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
429605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
429705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
429805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
429905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
430005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
430105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
430205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
430305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
430405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
430505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mDataOffset = 0;
430605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
430705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
430805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
430905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
431005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
431105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("MPEG4Extractor::parseTrackFragmentRun");
431205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (size < 8) {
431305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
431405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
431505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
431605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    enum {
431705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kDataOffsetPresent                  = 0x01,
431805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kFirstSampleFlagsPresent            = 0x04,
431905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleDurationPresent              = 0x100,
432005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleSizePresent                  = 0x200,
432105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleFlagsPresent                 = 0x400,
432205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        kSampleCompositionTimeOffsetPresent = 0x800,
432305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    };
432405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
432505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t flags;
432605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset, &flags)) {
432705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
432805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
432944a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // |version| only affects SampleCompositionTimeOffset field.
433044a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // If version == 0, SampleCompositionTimeOffset is uint32_t;
433144a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // Otherwise, SampleCompositionTimeOffset is int32_t.
433244a9bf5b013641a55d1784da353461e7446ff756Wei Jia    // Sample.compositionOffset is defined as int32_t.
433344a9bf5b013641a55d1784da353461e7446ff756Wei Jia    uint8_t version = flags >> 24;
433444a9bf5b013641a55d1784da353461e7446ff756Wei Jia    flags &= 0xffffff;
433544a9bf5b013641a55d1784da353461e7446ff756Wei Jia    ALOGV("fragment run version: 0x%02x, flags: 0x%06x", version, flags);
433605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
433705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
433805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // These two shall not be used together.
433905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
434005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
434105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
434205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t sampleCount;
434305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
434405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return ERROR_MALFORMED;
434505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
434605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    offset += 8;
434705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size -= 8;
434805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
434905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
435005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
435105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t firstSampleFlags = 0;
435205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
435305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kDataOffsetPresent) {
435405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
435505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
435605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
435705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
435805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int32_t dataOffsetDelta;
435905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) {
436005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
436105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
436205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
436305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
436405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
436505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
436605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
436705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
436805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
436905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kFirstSampleFlagsPresent) {
437005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (size < 4) {
437105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return -EINVAL;
437205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
437305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
437405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
437505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
437605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
437705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset += 4;
437805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size -= 4;
437905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
438005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
438105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
438205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen             sampleCtsOffset = 0;
438305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
438405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    size_t bytesPerSample = 0;
438505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleDurationPresent) {
438605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
438705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
438805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
438905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
4390c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    } else if (mTrex) {
4391c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        sampleDuration = mTrex->default_sample_duration;
439205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
439305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
439405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleSizePresent) {
439505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
439605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
439705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
439805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
439905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
440005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
440105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
440205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
440305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleFlagsPresent) {
440405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
440505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else if (mTrackFragmentHeaderInfo.mFlags
440605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
440705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
440805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
440905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
441005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
441105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
441205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (flags & kSampleCompositionTimeOffsetPresent) {
441305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bytesPerSample += 4;
441405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
441505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        sampleCtsOffset = 0;
441605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
441705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4418ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (size < (off64_t)(sampleCount * bytesPerSample)) {
441905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return -EINVAL;
442005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
442105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
442205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    Sample tmp;
442305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    for (uint32_t i = 0; i < sampleCount; ++i) {
442405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleDurationPresent) {
442505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleDuration)) {
442605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
442705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
442805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
442905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
443005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
443105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleSizePresent) {
443205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleSize)) {
443305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
443405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
443505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
443605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
443705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
443805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleFlagsPresent) {
443905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleFlags)) {
444005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
444105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
444205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
444305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
444405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
444505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (flags & kSampleCompositionTimeOffsetPresent) {
444605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
444705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_MALFORMED;
444805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
444905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            offset += 4;
445005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
445105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4452a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
4453ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen              " flags 0x%08x", i + 1,
445405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dataOffset, sampleSize, sampleDuration,
445505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                (flags & kFirstSampleFlagsPresent) && i == 0
445605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    ? firstSampleFlags : sampleFlags);
445705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.offset = dataOffset;
445805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.size = sampleSize;
445905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        tmp.duration = sampleDuration;
4460c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        tmp.compositionOffset = sampleCtsOffset;
446105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mCurrentSamples.add(tmp);
446205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
446305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        dataOffset += sampleSize;
446405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
446505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
446605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
446705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
446805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return OK;
446905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
447005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
447120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() {
44727b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
44737b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
447420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mFormat;
447520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
447620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const {
44786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    switch (mNALLengthSize) {
44796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 1:
44806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return *data;
44816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 2:
44826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U16_AT(data);
44836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 3:
44846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
44856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 4:
44866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U32_AT(data);
44876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
44886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
44896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // This cannot happen, mNALLengthSize springs to life by adding 1 to
44906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // a 2-bit integer.
44916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    CHECK(!"Should not be here.");
44926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
44936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    return 0;
44946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber}
44956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
449620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read(
449720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
44987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
44997b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
4500dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
450120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4502cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
4503cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        *out = nullptr;
4504cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        return WOULD_BLOCK;
4505cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
4506cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
450705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mFirstMoofOffset > 0) {
450805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return fragmentedRead(out, options);
450905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
451005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
451120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *out = NULL;
451220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4513abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    int64_t targetSampleTimeUs = -1;
4514abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
451520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int64_t seekTimeUs;
4516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
4517abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
4518abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t findFlags = 0;
4519abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        switch (mode) {
4520abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_PREVIOUS_SYNC:
4521abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagBefore;
4522abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4523abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_NEXT_SYNC:
4524abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagAfter;
4525abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4526abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST_SYNC:
4527abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST:
4528abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagClosest;
4529abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4530abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            default:
4531abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(!"Should not be here.");
4532abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
4533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4534abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
453520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t sampleIndex;
4536abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleTable->findSampleAtTime(
4537599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                seekTimeUs, 1000000, mTimescale,
4538abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                &sampleIndex, findFlags);
4539abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4540abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
4541abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // We found the closest sample already, now we want the sync
4542abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // sample preceding it (or the sample itself of course), even
4543abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // if the subsequent sync sample is closer.
4544abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            findFlags = SampleTable::kFlagBefore;
4545abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4546abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4547abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleIndex;
4548abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err == OK) {
4549abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            err = mSampleTable->findSyncSampleNear(
4550abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    sampleIndex, &syncSampleIndex, findFlags);
4551abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
455220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4553788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        uint32_t sampleTime;
4554788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        if (err == OK) {
4555788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber            err = mSampleTable->getMetaDataForSample(
4556788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber                    sampleIndex, NULL, NULL, &sampleTime);
4557788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber        }
4558788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber
455920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
45605295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            if (err == ERROR_OUT_OF_RANGE) {
45615295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // An attempt to seek past the end of the stream would
45625295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
45635295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // this all the way to the MediaPlayer would cause abnormal
45645295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // termination. Legacy behaviour appears to be to behave as if
45655295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // we had seeked to the end of stream, ending normally.
45665295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                err = ERROR_END_OF_STREAM;
45675295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            }
456805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGV("end of stream");
456920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
457020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
457120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4572abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
4573abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
4574abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4575abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4576abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0
4577abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleTime;
4578abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
4579abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    syncSampleIndex, NULL, NULL, &syncSampleTime));
4580abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4581df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("seek to time %lld us => sample at time %lld us, "
4582abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             "sync sample at time %lld us",
4583abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             seekTimeUs,
4584abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             sampleTime * 1000000ll / mTimescale,
4585abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             syncSampleTime * 1000000ll / mTimescale);
4586abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif
4587abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4588abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        mCurrentSampleIndex = syncSampleIndex;
458920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mBuffer != NULL) {
459020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
459120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
459220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
459320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
459420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // fall through
459520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
459620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
459765c954e72a126e4ea59d1fe2859bfb39cb800380Caroline Tice    off64_t offset = 0;
459865c954e72a126e4ea59d1fe2859bfb39cb800380Caroline Tice    size_t size = 0;
4599170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    uint32_t cts, stts;
46008bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    bool isSyncSample;
4601dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool newBuffer = false;
4602dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mBuffer == NULL) {
4603dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        newBuffer = true;
460420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4605c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err =
4606c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mSampleTable->getMetaDataForSample(
4607170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
460820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4609dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
4610dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
4611dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4612dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4613dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        err = mGroup->acquire_buffer(&mBuffer);
4614c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
4615dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
4616ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            CHECK(mBuffer == NULL);
4617dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
4618dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4619c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        if (size > mBuffer->size()) {
4620c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4621c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            return ERROR_BUFFER_TOO_SMALL;
4622c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        }
46230024245e134467d120b40099da16c467dc365e76Andreas Huber    }
462420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
4626dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (newBuffer) {
4627dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ssize_t num_bytes_read =
462834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
4629dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4630dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            if (num_bytes_read < (ssize_t)size) {
4631dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer->release();
4632dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer = NULL;
4633dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4634dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                return ERROR_IO;
4635dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            }
4636dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46377b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber            CHECK(mBuffer != NULL);
4638dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->set_range(0, size);
4639dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->meta_data()->clear();
464048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            mBuffer->meta_data()->setInt64(
46414678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4642170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            mBuffer->meta_data()->setInt64(
4643170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4644abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4645abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (targetSampleTimeUs >= 0) {
4646abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                mBuffer->meta_data()->setInt64(
4647abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                        kKeyTargetTime, targetSampleTimeUs);
4648abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
4649abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
46508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (isSyncSample) {
46518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
46528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
46538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4654dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ++mCurrentSampleIndex;
4655dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4656dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46573b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!mIsAVC && !mIsHEVC) {
4658dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            *out = mBuffer;
4659dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
4660dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4661dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return OK;
4662dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4663dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4664dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Each NAL unit is split up into its constituent fragments and
4665dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // each one of them returned in its own buffer.
4666dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize);
4668dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4669dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        const uint8_t *src =
4670dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
4671dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t nal_size = parseNALSize(src);
46735d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mNALLengthSize > SIZE_MAX - nal_size) {
46745d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen            ALOGE("b/24441553, b/24445122");
46755d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        }
46765d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
467729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("incomplete NAL unit.");
4678e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4679e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer->release();
4680e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer = NULL;
4681e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4682e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            return ERROR_MALFORMED;
4683e8a084958c27327b0aca749f69095605d2a21309Andreas Huber        }
4684dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4685dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        MediaBuffer *clone = mBuffer->clone();
46867b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(clone != NULL);
46876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
4688dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
46897b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(mBuffer != NULL);
4690dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mBuffer->set_range(
46916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_offset() + mNALLengthSize + nal_size,
46926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_length() - mNALLengthSize - nal_size);
4693dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4694dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (mBuffer->range_length() == 0) {
4695dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->release();
4696dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
4697dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4698dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4699dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        *out = clone;
4700dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4701dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        return OK;
4702dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    } else {
4703dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Whole NAL units are returned but each fragment is prefixed by
4704dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // the start code (0x00 00 00 01).
4705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        ssize_t num_bytes_read = 0;
4706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t drm = 0;
4707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
4708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
4709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read =
4710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
4711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
4712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
4713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
471420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
471520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (num_bytes_read < (ssize_t)size) {
471620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
471720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
471820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4719dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return ERROR_IO;
472020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
472120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
4723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
4724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, size);
47256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
4726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
4727dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t *dstData = (uint8_t *)mBuffer->data();
4728dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t srcOffset = 0;
4729dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t dstOffset = 0;
4730e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
4731dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (srcOffset < size) {
4732bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
473334fe252c89e33572d01fea981b58d7b115e76164James Dong                size_t nalLength = 0;
473434fe252c89e33572d01fea981b58d7b115e76164James Dong                if (!isMalFormed) {
473534fe252c89e33572d01fea981b58d7b115e76164James Dong                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
473634fe252c89e33572d01fea981b58d7b115e76164James Dong                    srcOffset += mNALLengthSize;
4737bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
473834fe252c89e33572d01fea981b58d7b115e76164James Dong                }
4739e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
474034fe252c89e33572d01fea981b58d7b115e76164James Dong                if (isMalFormed) {
474129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Video is malformed");
4742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer->release();
4743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer = NULL;
4744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return ERROR_MALFORMED;
4745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
4746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
4747dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (nalLength == 0) {
4748dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    continue;
4749dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
4750dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
475187afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                if (dstOffset > SIZE_MAX - 4 ||
475287afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                        dstOffset + 4 > SIZE_MAX - nalLength ||
475387afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                        dstOffset + 4 + nalLength > mBuffer->size()) {
475487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
475587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    android_errorWriteLog(0x534e4554, "27208621");
475687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    mBuffer->release();
475787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    mBuffer = NULL;
475887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                    return ERROR_MALFORMED;
475987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen                }
4760dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
4761dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4762dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4763dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
4764dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 1;
4765dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
4766dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                srcOffset += nalLength;
4767dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstOffset += nalLength;
4768dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
4769dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK_EQ(srcOffset, size);
4770dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
4771dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, dstOffset);
4772dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
4773dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
477420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->meta_data()->clear();
477548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        mBuffer->meta_data()->setInt64(
47764678a6dc5f09008481524949a9667af5a6190374Andreas Huber                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4777170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        mBuffer->meta_data()->setInt64(
4778170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
4779abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4780abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (targetSampleTimeUs >= 0) {
4781abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            mBuffer->meta_data()->setInt64(
4782abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    kKeyTargetTime, targetSampleTimeUs);
4783abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
4784abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
47854dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        if (mIsAVC) {
47864dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            uint32_t layerId = FindAVCLayerId(
47874dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
47884dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
47894dbff11975e737482537e1636051690188f3fbc4Praveen Chavan        }
47904dbff11975e737482537e1636051690188f3fbc4Praveen Chavan
47918bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (isSyncSample) {
47928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
47938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
47948bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
479520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        ++mCurrentSampleIndex;
479620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
479720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *out = mBuffer;
479820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
479920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
480020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
480120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
480220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
480320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
480405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead(
480505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MediaBuffer **out, const ReadOptions *options) {
480605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
480705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ALOGV("MPEG4Source::fragmentedRead");
480805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
480905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    CHECK(mStarted);
481005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
481105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *out = NULL;
481205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
481305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t targetSampleTimeUs = -1;
481405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
481505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    int64_t seekTimeUs;
481605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    ReadOptions::SeekMode mode;
481705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
481805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
481905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int numSidxEntries = mSegments.size();
482005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (numSidxEntries != 0) {
482105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            int64_t totalTime = 0;
482205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            off64_t totalOffset = mFirstMoofOffset;
482305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            for (int i = 0; i < numSidxEntries; i++) {
482405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                const SidxEntry *se = &mSegments[i];
482505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (totalTime + se->mDurationUs > seekTimeUs) {
482605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    // The requested time is somewhere in this segment
48273f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                    if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) ||
482805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
482905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
483005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        // requested next sync, or closest sync and it was closer to the end of
483105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        // this segment
483205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        totalTime += se->mDurationUs;
483305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        totalOffset += se->mSize;
483405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    }
483505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    break;
483605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
483705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                totalTime += se->mDurationUs;
483805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                totalOffset += se->mSize;
483905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
4840ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentMoofOffset = totalOffset;
4841ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            mNextMoofOffset = -1;
4842ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSamples.clear();
4843ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSampleIndex = 0;
4844ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseChunk(&totalOffset);
4845ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
4846ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
4847ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
4848ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentTime = totalTime * mTimescale / 1000000ll;
4849ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen        } else {
4850ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            // without sidx boxes, we can only seek to 0
4851ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentMoofOffset = mFirstMoofOffset;
4852ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            mNextMoofOffset = -1;
4853ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSamples.clear();
4854ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentSampleIndex = 0;
4855ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            off64_t tmp = mCurrentMoofOffset;
4856ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseChunk(&tmp);
4857ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
4858ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
4859ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
4860ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            mCurrentTime = 0;
486105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
486205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
486305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mBuffer != NULL) {
486405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
486505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
486605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
486705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
486805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // fall through
486905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
487005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
487105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    off64_t offset = 0;
4872442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber    size_t size = 0;
487305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t cts = 0;
487405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    bool isSyncSample = false;
487505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    bool newBuffer = false;
487605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (mBuffer == NULL) {
487705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        newBuffer = true;
487805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
487905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mCurrentSampleIndex >= mCurrentSamples.size()) {
48803f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            // move to next fragment if there is one
48813f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            if (mNextMoofOffset <= mCurrentMoofOffset) {
48823f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen                return ERROR_END_OF_STREAM;
48833f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen            }
4884ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            off64_t nextMoof = mNextMoofOffset;
488505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentMoofOffset = nextMoof;
488605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentSamples.clear();
488705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mCurrentSampleIndex = 0;
4888ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            status_t err = parseChunk(&nextMoof);
4889ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            if (err != OK) {
4890ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia                return err;
4891ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia            }
4892ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            if (mCurrentSampleIndex >= mCurrentSamples.size()) {
4893ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen                return ERROR_END_OF_STREAM;
4894ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen            }
489505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
489605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
489705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
489805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        offset = smpl->offset;
489905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size = smpl->size;
4900c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        cts = mCurrentTime + smpl->compositionOffset;
490105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mCurrentTime += smpl->duration;
490205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        isSyncSample = (mCurrentSampleIndex == 0); // XXX
490305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
490405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        status_t err = mGroup->acquire_buffer(&mBuffer);
490505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
490605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (err != OK) {
490705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer == NULL);
490805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGV("acquire_buffer returned %d", err);
490905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return err;
491005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
4911c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        if (size > mBuffer->size()) {
4912c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
4913c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen            return ERROR_BUFFER_TOO_SMALL;
4914c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen        }
491505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
491605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
491748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
491848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    const sp<MetaData> bufmeta = mBuffer->meta_data();
491948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    bufmeta->clear();
492048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    if (smpl->encryptedsizes.size()) {
492148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        // store clear/encrypted lengths in metadata
492248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyPlainSizes, 0,
492348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
492448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyEncryptedSizes, 0,
492548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
492648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
492748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
492848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
492948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen        bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
493048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen    }
493148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen
49323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) {
493305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (newBuffer) {
4934da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (!isInRange((size_t)0u, mBuffer->size(), size)) {
4935da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer->release();
4936da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer = NULL;
4937da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
4938da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
4939da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                return ERROR_MALFORMED;
4940da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
4941da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
494205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ssize_t num_bytes_read =
494305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
494405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
494505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (num_bytes_read < (ssize_t)size) {
494605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->release();
494705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer = NULL;
494805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
4949da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                ALOGE("i/o error");
495005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                return ERROR_IO;
495105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
495205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
495305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
495405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, size);
495505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt64(
495605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
4957170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            mBuffer->meta_data()->setInt64(
4958170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                    kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
495905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
496005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (targetSampleTimeUs >= 0) {
496105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->meta_data()->setInt64(
496205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                        kKeyTargetTime, targetSampleTimeUs);
496305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
496405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
49654dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            if (mIsAVC) {
49664dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                uint32_t layerId = FindAVCLayerId(
49674dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                        (const uint8_t *)mBuffer->data(), mBuffer->range_length());
49684dbff11975e737482537e1636051690188f3fbc4Praveen Chavan                mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
49694dbff11975e737482537e1636051690188f3fbc4Praveen Chavan            }
49704dbff11975e737482537e1636051690188f3fbc4Praveen Chavan
497105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            if (isSyncSample) {
497205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
497305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
497405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
497505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ++mCurrentSampleIndex;
497605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
497705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
49783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        if (!mIsAVC && !mIsHEVC) {
497905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            *out = mBuffer;
498005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
498105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
498205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return OK;
498305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
498405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
498505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // Each NAL unit is split up into its constituent fragments and
498605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // each one of them returned in its own buffer.
498705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
498805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(mBuffer->range_length() >= mNALLengthSize);
498905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
499005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        const uint8_t *src =
499105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
499205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
499305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        size_t nal_size = parseNALSize(src);
49945d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mNALLengthSize > SIZE_MAX - nal_size) {
49955d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen            ALOGE("b/24441553, b/24445122");
49965d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        }
49975d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen
49985d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
499905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            ALOGE("incomplete NAL unit.");
500005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
500105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
500205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
500305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
500405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_MALFORMED;
500505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
500605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
500705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MediaBuffer *clone = mBuffer->clone();
500805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(clone != NULL);
500905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
501005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
501105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        CHECK(mBuffer != NULL);
501205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer->set_range(
501305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->range_offset() + mNALLengthSize + nal_size,
501405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                mBuffer->range_length() - mNALLengthSize - nal_size);
501505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
501605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (mBuffer->range_length() == 0) {
501705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
501805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
501905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
502005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
502105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        *out = clone;
502205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
502305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
502405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    } else {
502505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ALOGV("whole NAL");
502605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // Whole NAL units are returned but each fragment is prefixed by
502705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        // the start code (0x00 00 00 01).
502805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ssize_t num_bytes_read = 0;
502905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        int32_t drm = 0;
503005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
5031da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        void *data = NULL;
5032da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        bool isMalFormed = false;
503305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (usesDRM) {
5034da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
5035da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = true;
5036da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            } else {
5037da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                data = mBuffer->data();
5038da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
503905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        } else {
5040da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            int32_t max_size;
5041da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mFormat == NULL
5042da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    || !mFormat->findInt32(kKeyMaxInputSize, &max_size)
5043da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    || !isInRange((size_t)0u, (size_t)max_size, size)) {
5044da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = true;
5045da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            } else {
5046da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                data = mSrcBuffer;
5047da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
504805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
504905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
5050da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        if (isMalFormed || data == NULL) {
5051da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            ALOGE("isMalFormed size %zu", size);
5052da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            if (mBuffer != NULL) {
5053da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer->release();
5054da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                mBuffer = NULL;
5055da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            }
5056da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            return ERROR_MALFORMED;
5057da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        }
5058da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih        num_bytes_read = mDataSource->readAt(offset, data, size);
5059da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih
506005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (num_bytes_read < (ssize_t)size) {
506105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->release();
506205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer = NULL;
506305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
5064da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih            ALOGE("i/o error");
506505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            return ERROR_IO;
506605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
506705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
506805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (usesDRM) {
506905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
507005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, size);
507105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
507205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        } else {
507305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            uint8_t *dstData = (uint8_t *)mBuffer->data();
507405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            size_t srcOffset = 0;
507505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            size_t dstOffset = 0;
507605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
507705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            while (srcOffset < size) {
5078da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
507905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                size_t nalLength = 0;
508005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (!isMalFormed) {
508105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
508205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    srcOffset += mNALLengthSize;
5083da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
5084da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
5085da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
508605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
508705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
508805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (isMalFormed) {
5089da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih                    ALOGE("Video is malformed; nalLength %zu", nalLength);
509005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    mBuffer->release();
509105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    mBuffer = NULL;
509205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    return ERROR_MALFORMED;
509305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
509405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
509505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                if (nalLength == 0) {
509605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    continue;
509705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                }
509805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
50995403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                if (dstOffset > SIZE_MAX - 4 ||
51005403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                        dstOffset + 4 > SIZE_MAX - nalLength ||
51015403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                        dstOffset + 4 + nalLength > mBuffer->size()) {
51025403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
51035403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    android_errorWriteLog(0x534e4554, "26365349");
51045403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    mBuffer->release();
51055403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    mBuffer = NULL;
51065403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                    return ERROR_MALFORMED;
51075403587a74aee2fb57076528c3927851531c8afbMarco Nelissen                }
510805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
510905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
511005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
511105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 0;
511205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstData[dstOffset++] = 1;
511305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
511405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                srcOffset += nalLength;
511505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                dstOffset += nalLength;
511605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            }
511705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK_EQ(srcOffset, size);
511805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            CHECK(mBuffer != NULL);
511905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->set_range(0, dstOffset);
512005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
512105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
512205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer->meta_data()->setInt64(
512305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
5124170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        mBuffer->meta_data()->setInt64(
5125170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih                kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
512605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
512705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (targetSampleTimeUs >= 0) {
512805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt64(
512905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen                    kKeyTargetTime, targetSampleTimeUs);
513005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
513105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
513205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        if (isSyncSample) {
513305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
513405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        }
513505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
513605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        ++mCurrentSampleIndex;
513705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
513805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        *out = mBuffer;
513905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        mBuffer = NULL;
514005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
514105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return OK;
514205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
514305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
514405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
5145bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
5146bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        const char *mimePrefix) {
5147bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    for (Track *track = mFirstTrack; track != NULL; track = track->next) {
5148bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        const char *mime;
5149bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        if (track->meta != NULL
5150bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                && track->meta->findCString(kKeyMIMEType, &mime)
5151bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber                && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
5152bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber            return track;
5153bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber        }
5154bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    }
5155bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber
5156bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber    return NULL;
5157bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber}
5158bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber
5159ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essickvoid MPEG4Extractor::populateMetrics() {
5160ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick    ALOGV("MPEG4Extractor::populateMetrics");
5161ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick}
5162ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick
51631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4(
5164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
516520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
516620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
516734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    ssize_t n = source->readAt(4, header, sizeof(header));
516820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (n < (ssize_t)sizeof(header)) {
516920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
517020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
517120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
517220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
5173b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
5174b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
51750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
5176ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
5177983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
517818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
51795a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        *confidence = 0.4;
518020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
518120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return true;
518220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
518320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
518420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return false;
518520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
518620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) {
51881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    static const uint32_t kCompatibleBrands[] = {
51891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', 'm'),
51901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', '2'),
51911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('a', 'v', 'c', '1'),
51923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        FOURCC('h', 'v', 'c', '1'),
51933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        FOURCC('h', 'e', 'v', '1'),
51941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('3', 'g', 'p', '4'),
51951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '1'),
51961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '2'),
51974cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong
51984cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        // Won't promise that the following file types can be played.
51994cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        // Just give these file types a chance.
52004cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
52014cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong        FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
520258fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber
520358fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber        FOURCC('3', 'g', '2', 'a'),  // 3GPP2
520458fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber        FOURCC('3', 'g', '2', 'b'),
52051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    };
52061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
52071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    for (size_t i = 0;
52081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
52091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         ++i) {
52101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        if (kCompatibleBrands[i] == fourcc) {
52111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            return true;
52121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
52131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
52141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
52151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
52161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
52171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
52181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable
52191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present.
5220a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends
5221a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of
5222a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata.
52231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4(
5224a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5225a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        sp<AMessage> *meta) {
5226a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    // We scan up to 128 bytes to identify this file as an MP4.
5227a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    static const off64_t kMaxScanOffset = 128ll;
52281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5229a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    off64_t offset = 0ll;
5230a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    bool foundGoodFileType = false;
5231a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    off64_t moovAtomEndOffset = -1ll;
5232a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    bool done = false;
52331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5234a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    while (!done && offset < kMaxScanOffset) {
5235a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint32_t hdr[2];
5236a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        if (source->readAt(offset, hdr, 8) < 8) {
5237a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            return false;
5238a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        }
5239a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5240a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint64_t chunkSize = ntohl(hdr[0]);
5241a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        uint32_t chunkType = ntohl(hdr[1]);
5242a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        off64_t chunkDataOffset = offset + 8;
5243a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5244a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        if (chunkSize == 1) {
5245a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
52461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                return false;
52471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
52481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5249a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            chunkSize = ntoh64(chunkSize);
5250a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            chunkDataOffset += 8;
5251a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5252a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            if (chunkSize < 16) {
5253a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                // The smallest valid chunk is 16 bytes long in this case.
5254a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                return false;
5255a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            }
5256452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen
5257a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        } else if (chunkSize < 8) {
5258a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            // The smallest valid chunk is 8 bytes long.
5259a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            return false;
5260a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        }
5261a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5262452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        // (data_offset - offset) is either 8 or 16
5263452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset);
5264452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        if (chunkDataSize < 0) {
5265452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen            ALOGE("b/23540914");
5266452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen            return ERROR_MALFORMED;
5267452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen        }
5268a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
526905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        char chunkstring[5];
527005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        MakeFourCCString(chunkType, chunkstring);
5271ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
5272a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        switch (chunkType) {
5273a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            case FOURCC('f', 't', 'y', 'p'):
5274a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            {
5275a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                if (chunkDataSize < 8) {
5276a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    return false;
5277a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
5278a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5279a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
5280a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
5281a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (i == 1) {
5282a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // Skip this index, it refers to the minorVersion,
5283a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // not a brand.
5284a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        continue;
5285a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
5286a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5287a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    uint32_t brand;
5288a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (source->readAt(
5289a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
5290a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        return false;
5291a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
5292a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5293a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    brand = ntohl(brand);
5294a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5295a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (isCompatibleBrand(brand)) {
5296a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        foundGoodFileType = true;
5297a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        break;
5298a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
5299a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
5300a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5301a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                if (!foundGoodFileType) {
5302a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    return false;
5303a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                }
5304a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
53051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                break;
53061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
5307a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5308a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            case FOURCC('m', 'o', 'o', 'v'):
5309a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            {
5310a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                moovAtomEndOffset = offset + chunkSize;
5311a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5312a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                done = true;
5313a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                break;
5314a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            }
5315a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5316a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber            default:
5317a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                break;
53181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
5319a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5320a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        offset += chunkSize;
53211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
53221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5323a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (!foundGoodFileType) {
53241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return false;
53251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
53261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
53271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
53285a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    *confidence = 0.4f;
53291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
5330a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (moovAtomEndOffset >= 0) {
5331a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        *meta = new AMessage;
5332a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
5333a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
5334ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset);
5335a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    }
5336a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
53371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return true;
53381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
53391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
53401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4(
53415a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5342a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        sp<AMessage> *meta) {
5343a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
53441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
53451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
53461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
53471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (LegacySniffMPEG4(source, mimeType, confidence)) {
53485ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
53491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
53501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
53511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
53521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
53531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
53541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
535520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
5356