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