MPEG4Extractor.cpp revision 58fb7c6e1a9244dd7215a647388c440d8d75851b
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen//#define LOG_NDEBUG 0 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1989e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <utils/Log.h> 27a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 28a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/MPEG4Extractor.h" 29a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/SampleTable.h" 30a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/ESDS.h" 31a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ABitReader.h> 33d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson#include <media/stagefright/foundation/ABuffer.h> 34ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 35a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 36bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 3758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar#include <media/stagefright/foundation/ColorUtils.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 4018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h> 46328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h" 47fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 48937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#ifndef UINT32_MAX 49937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#define UINT32_MAX (4294967295U) 50937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#endif 51937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 57942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen MPEG4Source(const sp<MPEG4Extractor> &owner, 58942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MetaData> &format, 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 6048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 6105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 6205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 63c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 6405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 7205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 75693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 76693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 787b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 80942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen // keep the MPEG4Extractor around, since we're referencing its data 81942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen sp<MPEG4Extractor> mOwner; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 83693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 85693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 8705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 8805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 89c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *mTrex; 9005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 9105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 9205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 9305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 9405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 9505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 98ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 99ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 10248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 1113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar bool mIsHEVC; 1126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 1136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1220024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1230024245e134467d120b40099da16c467dc365e76Andreas Huber 1246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 12505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 12605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 12705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 13305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 13405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 15105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 15205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 15305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 15405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 157c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t compositionOffset; 158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 16105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 16205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1636064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 179c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 180c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 183c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 192c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 227c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 230bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar if (isInRange(mCachedOffset, mCachedSize, offset, size)) { 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 238c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 246c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 26950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 27050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 27250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 273b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false; 274b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 279377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 31718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 32018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 322371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 32318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 324371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 32618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 329e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 330e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 33118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 33418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 34648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 34748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 34848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 35048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 35148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 35248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 35348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 35448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 35548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 35648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 35748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 35848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 35948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 360693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 361c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 362928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound(false), 363928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound(false), 36405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 365bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3667be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 367fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 36972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 370dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 371dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 372dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 385dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 3888da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 393ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 394ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 395ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 396ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 40005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 40105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 40205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 40305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 40405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 4067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 4077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 40872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4097be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 41172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 417ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 428a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 449371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 450371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 451371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 452371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 46005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 46105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 46205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 46305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 46405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 46505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 46605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 46705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 46805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 46905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 47005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 47105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 47305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 47405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 47505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 47605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 47705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4787e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4807e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4817e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 48648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 48748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 48848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 48948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 49048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 49148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 49248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 494bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 495bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 498c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 500928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang bool sawMoovOrSidx = false; 501928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 502928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) { 503a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 50405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 505a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 5064ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 5074ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 5084ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 509a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 510a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 511ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset); 512a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 513a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 514928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } else if (err == UNKNOWN_ERROR) { 515928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang sawMoovOrSidx = true; 51605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5187be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 519bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 52072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 521bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 522bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 52372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 52472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 52572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 526bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 527bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 530bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 531ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 532ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 533c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen uint64_t psshsize = 0; 534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 535ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 536ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 537c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (psshsize > 0 && psshsize <= UINT32_MAX) { 538ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 540ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 541ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 542ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 543ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 544ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 545ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 546ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 547ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 548bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 558dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 559dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 560dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 561dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 562dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 563dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 564dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 565dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 566dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 567dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 568dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 569dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 571dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 572dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 573dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 574dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 575dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 59084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 59184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 7008da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 7018da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 7028da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 7038da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 704f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 706f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 72272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 72372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 72472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 72572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 72672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 72772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 72972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 73072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 73172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 73372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 73472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 73672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 73772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 73872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 74072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 74172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 74272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 74372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 74472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 74572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 74672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 7478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) { 7488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return path.size() >= 2 7498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[0] == FOURCC('m', 'o', 'o', 'v') 7508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[1] == FOURCC('m', 'e', 't', 'a') 7518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && (depth == 2 7528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || (depth == 3 753ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang && (path[2] == FOURCC('h', 'd', 'l', 'r') 754ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang || path[2] == FOURCC('i', 'l', 's', 't') 7558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || path[2] == FOURCC('k', 'e', 'y', 's')))); 7568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 7578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 76372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 76472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 76672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 76772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 768c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 769ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth); 770452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 771452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (*offset < 0) { 772452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 773452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 774452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 77634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 7802d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer int32_t chunk_type = ntohl(hdr[1]); 781c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 78434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 78971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 79071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 79171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 79271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 79371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 794a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 795a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 796a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 797a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 798a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 799a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 800a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 801a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 802a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 803a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 804a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 805a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 806a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 807a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 808a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 809a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 81071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 81171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 812a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 81371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 818ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth); 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 820b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 821b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe static const char kWhitespace[] = " "; 822b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 823b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 825b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe char buffer[256]; 826b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t n = chunk_size; 827b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (n > sizeof(buffer)) { 828b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe n = sizeof(buffer); 829b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 830b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (mDataSource->readAt(*offset, buffer, n) 831b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe < (ssize_t)n) { 832b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return ERROR_IO; 833b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 834ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 835b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(buffer, n); 836b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 83972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 840452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - *offset) is either 8 or 16 841452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunk_data_size = chunk_size - (data_offset - *offset); 842452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunk_data_size < 0) { 843452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 844452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 845452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 848515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 84972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 850c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 85172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 85272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 85372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 85472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 85572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 85672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 85772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 858bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 859bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 860bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 861bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 86272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 86372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 86472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 86572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 87420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 87772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 87872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 879ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 880ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 8810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 883928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) { 884928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang // store the offset of the first segment 885928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound = true; 886928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofOffset = *offset; 887928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } 888928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 88950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 890a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 89150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 892b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 893b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 894b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 89550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 89650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 89750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 89850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 89950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 90050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 90150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 9021edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 903f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 904f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 905f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 9061edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 90750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 90850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9096f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 910bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 9116f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 9126f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 915bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 916bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 917bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 918bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 919bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 920bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 921bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 922bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 923bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 9246f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 925bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 926bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 927bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 928bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 929c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 938bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 939bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 940bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 941bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 9426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 9430386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia int32_t trackId; 9440386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia // There must be exact one track header per track. 9450386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 9460386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia mLastTrack->skipTrack = true; 9470386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } 9486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 9496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 9506f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9516f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 9526f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 9536f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 9546f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 9556f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 9566f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 9576f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9586f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 9596f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 9606f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 9616f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9626f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9636f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 9646f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9656f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 966bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 967bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 968bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 969bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 970bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 971bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 972bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 974dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 975dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 976dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 977dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 978dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 9840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 9850517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 9860517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 9870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 9880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 9890a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 9900a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9910a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9920a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 9940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 9950a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9960a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9970a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9980a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 9990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 10000a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 1001fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 1002210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 10030a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10040a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 10050a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 10060a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 10070a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10080a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 10090a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 10100a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 10110a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10120a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10130a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 10140a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 10150a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 10160a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 10170a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 10180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 10210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 10220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10250a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1026fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 1027fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 1028fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 10290a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10300a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 10310a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 10321391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 10331391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 10341391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 10350a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 10360a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 10370a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10380a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 10390a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 10400a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1041608fe1d6b2ea4d88245a109afe2bfba580881a16Wei Jia int64_t paddingus = duration - (int64_t)(segment_duration + media_time); 1042465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1043465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1044465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1045465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1046465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1047465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 10480a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 10490a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 10500a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10510a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 10530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10570517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10580517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 105948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1065f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1066f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1067f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1068f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 107048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 107148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 107248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 107348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 107448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 107548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10810517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10820517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1116ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1124f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1125f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1126f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1127ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 113320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 113420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11350517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11360517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1137ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1138ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1139ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 114020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 114320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11470517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1161c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (chunk_size < 20 || pssh.datalen > chunk_size - 20) { 1162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11668da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 11678da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 11688da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 11698da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1173ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1174ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1175ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1176ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1177ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1178ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11820517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11830517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1184202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 118934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 119220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1195c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 119620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 120020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 120120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 120220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 120320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 120634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 120720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 120820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 120920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 121020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12122e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (!timescale) { 12132e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale should not be ZERO."); 12142e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 12152e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 12162e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 121720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 121820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1219c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1220c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 122105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 122220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 122334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1228c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1229c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1230c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 123205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 123334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 123905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 124005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1242e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mLastTrack->timescale != 0) { 1243c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1244c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1245c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 124620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 12487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 12497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 12507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 12517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 12527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 12537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 12547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 12587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 12597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 12637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 12647a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 12657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 12667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 12677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 12687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 12697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 12707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 12727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 12737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 128120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1284c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1285bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1286bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1287bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 128834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 129120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 129920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 13013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 13023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 13033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1304ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 13053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 1306f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1307f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1308f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1309f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 13103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1311ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1312ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 13133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 13143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 13153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 13163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 13173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 131820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1319c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 132020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 132120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 132220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1327bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1328bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1329bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1330bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 133120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 133320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 133548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 133620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 133820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 133920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 134120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 134220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1350b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 135148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 135481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 135581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1356f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1357f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1358f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 135948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 136048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 136148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 136248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 136581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1369c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 137320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 137420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 137520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1377bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1378bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1379bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1380bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 138220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 138420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1385ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 138620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1387e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1388e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 13903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 13913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 13937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 13947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 139520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 139620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 140320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1406b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1410ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1411a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1412a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1413a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1414a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1415a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1416a6256238d9015c42129fe43791968768fe501efaJames Dong 1417134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1418134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 141920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1420f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1421f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1422f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1423ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1424ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1425ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1426ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1430c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 143220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 143520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1438bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1439bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1440bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1441bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 144620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 144720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1448274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1449274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1450274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 145120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 145220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 145720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 146520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1466274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1467274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1468274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 146920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 147220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14730517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14740517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 147520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 148120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 148220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 148320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 148420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1485274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1486274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1487274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 148820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 148920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 149020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 149120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14930517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 149420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 149520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 149720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1498738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 149949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 150049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 150149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 150249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 150349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1504738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 150505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 150605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 150705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 150805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 150905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 1510beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (max_size > SIZE_MAX - 10 * 2) { 1511beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("max sample size too big: %zu", max_size); 1512beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1513beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 151405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 151505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 151605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 1517beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen uint32_t width, height; 1518beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) || 1519beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) { 152005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1521f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1522f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 1523beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } else { 1524beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // A resolution was specified, check that it's not too big. The values below 1525beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // were chosen so that the calculations below don't cause overflows, they're 1526beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // not indicating that resolutions up to 32kx32k are actually supported. 1527beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (width > 32768 || height > 32768) { 1528beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("can't support %u x %u video", width, height); 1529beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1530beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 153105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1532f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 15334256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 15344256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1535f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1536f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // AVC requires compression ratio of at least 2, and uses 1537f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1538f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1539f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1540f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1541f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1542f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 154305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1544f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 154505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1546113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 15474256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 15484256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1549113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1550113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1551113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1552113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1553113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1554113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1555113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1556113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1557113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1558113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1559113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1560113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1561113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1562113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1563113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 156720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 156820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1569274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1570274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1571274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15720517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15730517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 157420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 157520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 157620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 157720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 157820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 157920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 158020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 15864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 1587274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1588274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1589274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15900517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15910517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 15924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 15934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 15944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 15954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 15974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 15984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15994931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 16004931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 16014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 16024931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 160320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 160420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1605274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1606274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1607274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16090517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 161020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 161120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 161220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 161320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 161520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1621afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // \xA9xyz 1622e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh case FOURCC(0xA9, 'x', 'y', 'z'): 16234948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 16240517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1626afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // Best case the total data length inside "\xA9xyz" box 1627afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/", 16284948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 16294948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 16304948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 16314948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 16324948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16334948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16344948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16354948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 16364948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 16374948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 16384948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 16394948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16404948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 16414948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 16424948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 16434948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 16444948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16454948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16464948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16474948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 16484948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 16494948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 16504948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16514948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16524948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 16534948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 16544948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 16554948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16564948818cb91176df74c972ac27b2f392b5d148bcJames Dong 165720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 165820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 16590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 166120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 166220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 166320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1666c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 166720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 167120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 167420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 167620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 167720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 167820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 167920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1680f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1681f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1682f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 168320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 168420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 168520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1686ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1687ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1688ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1689ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1690ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1691ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1692ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1693ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1694ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1695ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1696ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1697ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1698ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1699ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1700ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (mPath.size() >= 2 1701ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) { 1702ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar // Check if the video is MPEG2 1703ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar ESDS esds(&buffer[4], chunk_data_size - 4); 1704ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar 1705ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar uint8_t objectTypeIndication; 1706ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) { 1707ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) { 1708ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); 1709ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1710ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1711ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 171220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 171320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 171420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 171520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 171620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 17170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1719d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 172020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1722d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1726f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1727f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1728f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 172920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1730d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 173320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 17353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 17363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 17373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 17383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 17393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 17403b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 17413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 17423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 1743f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1744f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1745f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 17463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 17473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 17483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 17493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 17503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 17513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 175220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1753244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1754244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 17550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 175617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 175717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 175817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 175917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 176017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 176117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 176217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 176317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 176417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 176517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 176617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 176717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 176817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 176917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1770ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size); 1771244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1772244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1773244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1774244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1775244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1776244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1777244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1778244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1779f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1780f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1781f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1782244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1783244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1784244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1785244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1786244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 178772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 178872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stop_offset = *offset + chunk_size; 17908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset = data_offset; 17918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang bool isParsingMetaKeys = underQTMetaPath(mPath, 2); 17928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!isParsingMetaKeys) { 17938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint8_t buffer[4]; 17948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (chunk_data_size < (off64_t)sizeof(buffer)) { 17958ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 17968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 17978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 1798bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 17998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 18008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang data_offset, buffer, 4) < 4) { 18018ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 18028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_IO; 18038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 180472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 18058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (U32_AT(buffer) != 0) { 18068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // Should be version 0, flags 0. 1807ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 18088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // If it's not, let's assume this is one of those 18098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // apparently malformed chunks that don't have flags 18108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // and completely different semantics than what's 18118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // in the MPEG4 specs and skip it. 18128ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 18138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 18148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 18158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += sizeof(buffer); 181672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 181772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 181872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 181972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 182072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 182172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 182272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 182372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1824bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1825bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1826bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1827bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 182872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 182972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 183072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 18315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 18325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 183372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 183472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 18350517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18360517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 183772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1838fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 183972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 184072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 184172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 184272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 184372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 184472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 184572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 184672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 184772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 184872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 184972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 18500517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1852c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 185372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 185472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 185572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1856c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 185772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 185872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 185972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 186072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 186172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 186272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1863fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 1864c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 186572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 186672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1867fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1868c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 1869c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1870c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1871c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1872bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1873bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 187472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 187572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1876fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 1877c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 1878c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1879c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1880c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1881c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1882c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1883e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 1884c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 188572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 188672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 188772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 188872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 188972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 189072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 189172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 189272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 189372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 189472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1895c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 1896c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1897c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1898c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1899c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 1900c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1901c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1902c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1903c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 1904c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 1905c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 1906c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 1907c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1908c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1909c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1910c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 1911c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 1912c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 1913c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 1914c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1915c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1916c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 1917c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1918c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1919c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1920c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 1921c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 1922c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 1923c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 1924c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1925c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1926c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1927c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1928c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 1929c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1930c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1931c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1932e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 1933c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 1934c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1935c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1936c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1937c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1938c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1939dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1940dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1941ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 1942928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 1943928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound = true; 1944928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 1945dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1946dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1947dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1948dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1949dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1950dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1951dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1952dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1953dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1954dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1955dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1956dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 19573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 19583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 19590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1961ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang if (underQTMetaPath(mPath, 3)) { 1962ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang break; 1963ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang } 1964ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang 19653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 19663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 19673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 19683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 19693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 19723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1973e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1974e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1975e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 1976cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar if (mLastTrack != NULL) { 1977cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 1978cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar } 19793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 19823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang case FOURCC('k', 'e', 'y', 's'): 19858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang { 19868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 19878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 19888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 19898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaKey(data_offset, chunk_data_size); 19908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 19918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang break; 19928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 19938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 1994c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 1995c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1996c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1997c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1998c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 1999c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2000c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2001c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 2002c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 2003c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 2004c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 2005c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 2006c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 2007c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2008c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2009c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 2010c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2011c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2012c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 20137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 20147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 2015f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2016f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2017f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 20183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 20193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 20203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 20213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 20223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 20233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 20243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20260e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) { 2027dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake return ERROR_MALFORMED; 2028dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake } 2029dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake 20308da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 20318da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 20328da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 20338da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 20343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 20363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 20373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 20403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 20413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 20423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 20433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20440517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 20450517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 20473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 20503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 20513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 20537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 20547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 20557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 20567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 20577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 2058515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 2059515e855eae78aa495da58356486aaa666cb57fd1James Dong { 20600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20610517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2062515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 2063635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, 2064635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert chunk_data_size, data_offset); 20651e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake 2066635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) { 20671e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake return ERROR_MALFORMED; 20681e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake } 20691552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 2070515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 20711552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 2072515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 2073515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2074515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 207597d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake if (chunk_data_size <= kSkipBytesOfDataBox) { 207697d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake return ERROR_MALFORMED; 207797d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake } 207897d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake 2079515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 2080515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 20811552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 2082515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2083515e855eae78aa495da58356486aaa666cb57fd1James Dong 2084515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 2085515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2086515e855eae78aa495da58356486aaa666cb57fd1James Dong 208758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar case FOURCC('c', 'o', 'l', 'r'): 208858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar { 208958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar *offset += chunk_size; 209058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd') 209158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // ignore otherwise 209258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) { 209358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar status_t err = parseColorInfo(data_offset, chunk_data_size); 209458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (err != OK) { 209558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return err; 209658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 209758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 209858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 209958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar break; 210058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 210158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2102fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2103fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2104fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2105fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2106fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2107fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2108fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 21090517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21100517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2111fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 2112fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2113fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 2114fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 2115fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2116fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2117fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2118fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2119fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2120328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 2121328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 21220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21230517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2124328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 2125328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 2126328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2127328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2128328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 2129328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2130328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 2131328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2132328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 21335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 21345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 21355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 21365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 21375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 21385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 21395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21405d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 21415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 214205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 214305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 214405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 214505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 214605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 214705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 214805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 214920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 215020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 21518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // check if we're parsing 'ilst' for meta keys 21528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // if so, treat type as a number (key-id). 21538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 21548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaVal(chunk_type, data_offset, chunk_data_size); 21558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 21568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 215720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 215820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 215920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 216020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 216120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 216220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 216320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 216420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 216505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 216605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 216705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 216805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 216905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 217005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 217105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 217205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 217305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 217405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 217505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 217605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 217705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 217805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 217905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 218005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 218105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 218205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 218305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 218405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 218505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 218605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 218705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 218805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 218905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 219005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 219105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 2192e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (timeScale == 0) 2193e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake return ERROR_MALFORMED; 219405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 219505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 219605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 219705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 219805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 219905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 220005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 220105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 220205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 220305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 220405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 220505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 220605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 220705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 220805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 220905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 221005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 221105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 221205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 221305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 221405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 221505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 221605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 221705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 221805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 221905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 222005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 222105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 222205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 222305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 222405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 222505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 222605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 222705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 222805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2229a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 223005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 223105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 223205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 223305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 223405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 223505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 223605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 223705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 223805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 223905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 224005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 224105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 224205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 224305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 224405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 224505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 224605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 224705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 224805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 224905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 225005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 225105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 225205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 225305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 225405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 225505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 225605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 225705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 225805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 225905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 226005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 22613f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 22623f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 22633f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 22643f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 226505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 226605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 226705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 226805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 226905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 227005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 227105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 227205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 227305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 227405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2275c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 227605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2277f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2278f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2279f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 228005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 228105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2282c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 228305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 228405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 228505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 228605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 22878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) { 22888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size < 8) { 22898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t count; 22938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &count)) { 22948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mMetaKeyMap.size() > 0) { 22988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGW("'keys' atom seen again, discarding existing entries"); 22998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.clear(); 23008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t keyOffset = offset + 8; 23038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stopOffset = offset + size; 23048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang for (size_t i = 1; i <= count; i++) { 23058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyOffset + 8 > stopOffset) { 23068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t keySize; 23108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset, &keySize) 23118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keySize < 8 23128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keyOffset + keySize > stopOffset) { 23138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t type; 23178cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset + 4, &type) 23188cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || type != FOURCC('m', 'd', 't', 'a')) { 23198cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23208cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23218cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keySize -= 8; 23238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += 8; 23248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang sp<ABuffer> keyData = new ABuffer(keySize); 23268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyData->data() == NULL) { 23278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 23308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset, keyData->data(), keySize) < (ssize_t) keySize) { 23318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang AString key((const char *)keyData->data(), keySize); 23358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.add(i, key); 23368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += keySize; 23388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 23408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 23418cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal( 23438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang int32_t keyId, off64_t offset, size_t size) { 23448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ssize_t index = mMetaKeyMap.indexOfKey(keyId); 23458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (index < 0) { 23468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // corresponding key is not present, ignore 23478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 234905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 23508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size <= 16) { 23518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataSize; 23548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &dataSize) 23558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || dataSize > size || dataSize <= 16) { 23568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t atomFourCC; 23598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &atomFourCC) 23608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || atomFourCC != FOURCC('d', 'a', 't', 'a')) { 23618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataType; 23648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 8, &dataType) 23658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || ((dataType & 0xff000000) != 0)) { 23668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // not well-known type 23678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang dataSize -= 16; 23718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang offset += 16; 23728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (dataType == 23 && dataSize >= 4) { 23748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // BE Float32 23758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t val; 23768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &val)) { 23778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) { 23808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val); 23818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } else { 23838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // add more keys if needed 23848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGV("ignoring key: type %d, size %d", dataType, dataSize); 23858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 23888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 238905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2390ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2391c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2392ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2393ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2394ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2395ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2396ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2397ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2398ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2399ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2400ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2401ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2402ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2403ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2404ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2405c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2406ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2407ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2408ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2409ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2410ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2411ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2412ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2413ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2414b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint64_t ctime __unused, mtime __unused, duration __unused; 2415ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2416ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2417ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2418ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2419ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2420ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2421ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 242204022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2423ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2424ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2425ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2426ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 242704022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 242804022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2429ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2430ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2431f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2432f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2433f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2434ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2435ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2436ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2437ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2438ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2439ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2440ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2441ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2442ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2443b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2444b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2445b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 2446df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2447ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2448df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2449ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2450ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2451ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2452ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2453ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2454ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2455ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2456ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2457ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2458ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2459ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2460ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2461ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2462ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2463ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2464ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 24655ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2466ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2467ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2468ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2469ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2470ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2471ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2472ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2473b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2474b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2475ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2476ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2477b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2478b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2479ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2480ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2481ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2482ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2483fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 2484c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich if (size < 4 || size == SIZE_MAX) { 248572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 248672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 248772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 24888da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 24898da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 24908da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 24918da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 249272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 249372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 249472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 249572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 249672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 249772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 249872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 249972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 250072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 250172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 250272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 25035d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 25045d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 2505ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("meta: %s @ %lld", chunk, (long long)offset); 25062d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer switch ((int32_t)mPath[4]) { 250772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 250872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 250972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 251072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 251172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 251272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 251372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 251472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 251572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 251672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 251766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 251866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 251966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 252066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 252166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 252272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 252372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 252472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 252572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 252672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 252772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 252872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 252972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 253072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 253172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 253272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 253372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 253472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 253572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 253672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 253772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 253872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 253972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 254072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 254172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 254272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 254372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 254472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 254572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 254672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 254726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 254826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 254926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 255026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 255126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 255211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 255311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 255411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 255511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 255611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 255711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 255811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 255911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 256011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 256111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 256211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 256372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 256472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 256572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 256672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2567afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2568afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2569afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 257072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 257172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 257272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 257372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 257472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 257526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 257626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2577afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 257826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2579afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2580afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2581afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 258226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 258326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 258426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 258526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 258626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 25875d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 25885d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 25895d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 25905d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 25915d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 25925d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 25935d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 25945d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 25955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 25965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 25975d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 25985cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia if (size < 8) { 25995cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia delete[] buffer; 26005cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia buffer = NULL; 26015cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia ALOGE("b/24346430"); 26025cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia return ERROR_MALFORMED; 26035cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia } 26045d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 26055d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 26065d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 26078c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 26088c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 26098c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 26108c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 26118c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 26128c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 26138c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 26148c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 26158c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 26168c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 26178c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 26188c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 26198c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 26208c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 26218c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 2622f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2623f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2624f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 26258c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 26268c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 26278c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 26285d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 26298c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 26305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 26315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 26325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 26335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 26345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 26355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 263626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 263772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 263872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 263972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 264072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2641328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 264272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 264372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 264472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 264572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 264672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 264772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 264826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 264926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 265026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 265126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 265226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 265326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 265426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 265526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 265626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 265772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 265826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 265972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 266072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 266126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 266226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 266326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 266426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 266526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 266626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 266772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 266872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 266972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 267072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 267172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 267272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 267372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 267472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 267572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 267672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 267772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 267872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 267972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 268072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 268172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 268258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { 268358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) { 268458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 268558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 268658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 268758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 268858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (buffer == NULL) { 268958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 269058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 269158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) { 269258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 269358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 269458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 269558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_IO; 269658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 269758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 269858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t type = U32_AT(&buffer[0]); 269958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11) 270058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) { 270158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t primaries = U16_AT(&buffer[4]); 270258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t transfer = U16_AT(&buffer[6]); 270358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t coeffs = U16_AT(&buffer[8]); 270458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128); 270558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 270658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorAspects aspects; 270758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorUtils::convertIsoColorAspectsToCodecAspects( 270858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar primaries, transfer, coeffs, fullRange, aspects); 270958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 271058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // only store the first color specification 271158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { 271258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); 271358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); 271458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); 271558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); 271658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 271758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 271858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 271958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 272058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 272158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 272258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return OK; 272358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar} 272458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2725fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 27265cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake if (size < 4 || size == SIZE_MAX) { 2727fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2728fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2729fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 27305cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 27318da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 27328da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 27338da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 2734fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2735fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2736fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2737fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2738fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2739fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2740fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2741fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2742fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2743fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2744fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2745fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2746fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2747fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2748fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2749fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2750fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2751fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2752fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2753fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2754fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2755fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2756fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2757fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2758fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2759fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2760fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2761fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2762fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2763fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2764fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2765fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2766fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2767fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2768fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2769fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2770fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2771fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2772fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2773fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2774fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2775fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2776fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2777fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2778fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2779fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2780fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2781fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2782fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2783fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2784fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2785fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2786fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2787fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2788fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2789fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2790fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2791fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2792fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2793fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2794fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2795fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2796fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2797fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2798fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 27999458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake if (size < 6) { 28009458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake return ERROR_MALFORMED; 28019458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake } 28029458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake 2803fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2804fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2805fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2806fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2807fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2808fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2809fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2810fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2811fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2812fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2813fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2814fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2815fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2816fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2817fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2818fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2819fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2820fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2821fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2822fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2823fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2824fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2825fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 28265cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake buffer[size] = 0; 2827fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2828fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2829fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2830fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2831fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2832fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2833fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2834fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2835fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2836fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2837fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2838fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2839fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2840fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2841328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2842328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2843328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2844328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2845328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2846328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2847328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2848328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2849328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2850328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2851328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2852328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2853328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2854328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2855328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2856328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2857328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2858328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2859328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2860328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2861328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2862328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2863328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2864328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2865328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2866328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2867328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2868328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2869328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2870328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2871328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2872328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2873328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2874328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2875328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2876328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2877328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2878328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2879328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2880328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2881328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2882328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2883328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2884328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2885328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2886328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2887328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2888328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2889328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2890328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2891328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2892328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2893328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2894328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2895328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2896328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2897b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) { 289820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 289920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2900693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 290120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 290220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 290320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 290420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 290520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2906693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 290720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 290820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 290920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 291020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 291120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 291220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2913371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 2914371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 2915371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 2916371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2917c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2918c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 2919c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 2920c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 2921c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 2922c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *t = &mTrex.editItemAt(index); 2923c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 2924c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 2925c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2926c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2927c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 29280386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } else { 29290386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia ALOGE("b/21657957"); 29300386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia return NULL; 2931c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2932c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2933a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 2934ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2935a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const char *mime; 2936a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findCString(kKeyMIMEType, &mime)) { 2937a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 2938a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 2939a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 2940a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2941a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 2942a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 2943a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 2944a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) { 2945a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 2946a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 2947a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 2948a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 2949a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 2950a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 2951a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 2952a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 2953a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 2954a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 2955a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 2956a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 2957a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) { 2958a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 2959a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 2960a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 2961a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 2962a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 2963a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 22 || ptr[0] != 1) { // configurationVersion == 1 2964a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 2965a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 2966a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 2967a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 2968942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen return new MPEG4Source(this, 296905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 2970c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 297120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 297220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2973bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 2974bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 2975bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 2976bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2977bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2978bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 2979bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 2980bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 2981bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2982bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2983bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 2984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2985bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 29863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 29873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 29883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 29893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 29903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 2991bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2992ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) 2993bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2994bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2995bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 2996bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2997bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2998bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2999bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3000ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 3001169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 3002ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 3003169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 3004169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 3005169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 30062e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (track->timescale == 0) { 30072e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale invalid."); 30082e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 30092e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 30102e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 3011bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 3012bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 3013bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3014f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 3015f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 3016f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 3017f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 3018f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 3019f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 3020f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 3021f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 3022f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 3023f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 3024f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 3025f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 3026f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 3027f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 3028f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 3029f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 3030f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 3031f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 3032f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 3033f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 3034f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 3035f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 3036f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 3037f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 3038f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 3039f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 3040f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 3041f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 3042f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 3043f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 3044f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 3045f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 3046f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 3047f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3048f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 3049f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3050f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 3051f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 3052f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 3053f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 3054f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 3055f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 3056f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 3057f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 3058f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3059f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 3060f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 3061f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 3062f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3063f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 3064f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 3065f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3066ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 3067ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 3068ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 306981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 307081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 307181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 307281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 307381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 307481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 307581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 307681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 3077f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3078f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3079f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 308081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 308181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 308281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 308381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 3084633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 3085633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 3086633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 3087633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 308829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 3089633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 3090633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 3091633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 3092ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 3093ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 3094ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 3095ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 3096ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3097ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3098ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3099b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 3100ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar printf("ESD of size %zu\n", csd_size); 3101b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(csd, csd_size); 3102b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 3103ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3104a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 3105a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 3106a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 3107a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 3108a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3109a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 3110a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 3111a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3112ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 3113ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3114ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3115ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 311600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 311700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 311800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 311900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 312000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 3121aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 3122aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 3123ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3124aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 3125aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 3126ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3127ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3128f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3129f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3130f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3131db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 3132db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 3133db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 3134aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 3135aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 3136ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 3137ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 3138ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 31398e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 28) return ERROR_MALFORMED; 3140aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 3141aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 3142ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 31438e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3144595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 314500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 314600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 314700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 3148ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3149ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 315000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 315100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 3152595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 3153f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 31548e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 315500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 3156b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t extSampleRate __unused; 315700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 315800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 3159595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 3160595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 31618e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 24) return ERROR_MALFORMED; 316200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 316300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 316400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 316500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 316600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 316700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 3168595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 316900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 317000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 3171ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3172ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3173f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 3174f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 3175f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 3176f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 3177f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 3178f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 3179f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 3180f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 3181f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 3182f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 3183f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3184f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 3185f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 3186f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3187f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 3188f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 3189f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 3190f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 3191f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3192f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 3193f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 3194f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3195f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3196f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 3197f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 31988e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3199f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 3200f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3201f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 32028e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 6) return ERROR_MALFORMED; 3203f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 3204f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3205f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3206f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 3207f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 3208f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 32098e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 2) return ERROR_MALFORMED; 3210b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t frameLengthFlag __unused = br.getBits(1); 3211f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3212f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 3213f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3214f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 32158e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 14) return ERROR_MALFORMED; 3216b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t coreCoderDelay __unused = br.getBits(14); 3217f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3218f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 321945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 322045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 322145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 322245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 322345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 322445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 322545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 322645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 322745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 322845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 322945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 323045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 323145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 323245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 323345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 323445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 32358e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 323645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 323745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 323845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 323945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 324045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 3241f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 324245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 3243f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 3244f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 32458e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 32) { 32468e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 32478e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen } 3248b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t ElementInstanceTag __unused = br.getBits(4); 3249b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t Profile __unused = br.getBits(2); 3250b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SamplingFrequencyIndex __unused = br.getBits(4); 3251f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 3252f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 3253f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 3254f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 3255b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumAssocDataElements __unused = br.getBits(3); 3256b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumValidCcElements __unused = br.getBits(4); 3257f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3258f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 32598e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen 3260f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 32618e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3262b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MonoMixdownElementNumber __unused = br.getBits(4); 3263f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3264f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 32658e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3266f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 3267f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 32688e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3269b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t StereoMixdownElementNumber __unused = br.getBits(4); 3270f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3271f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 32728e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3273f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 3274f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 32758e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 3) return ERROR_MALFORMED; 3276b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MatrixMixdownIndex __unused = br.getBits(2); 3277b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t PseudoSurroundEnable __unused = br.getBits(1); 3278f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3279f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3280f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 3281f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 32828e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3283f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 3284b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t FrontElementTagSelect __unused = br.getBits(4); 3285f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 3286f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3287f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3288f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 32898e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3290f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 3291b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SideElementTagSelect __unused = br.getBits(4); 3292f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 3293f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3294f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3295f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 32968e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3297f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 3298b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t BackElementTagSelect __unused = br.getBits(4); 3299f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 3300f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3301f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 3302f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3303f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 33048e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3305b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t LfeElementTagSelect __unused = br.getBits(4); 3306f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 3307f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3308f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 3309f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 3310f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 3311f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3312f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3313f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3314f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3315ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 3316ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 3317ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3318ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3319f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3320f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3321f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3322ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 3323ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 3324ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3325ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 33263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 3327ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 3328ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3329ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3330ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 3331ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3332ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 3333ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 3334ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3335ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 33363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 3337ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 3338ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3339ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3340ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 3341ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3342ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 3343ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 3344ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 334520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 334620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 334720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 3348942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 334920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 3350693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 335148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 335205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 335305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 3354c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 335505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 3356942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 3357942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 335820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 335948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 336020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 336120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 336205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 336305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 3364c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 336505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 336605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 336705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 3368ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 3369ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 3370ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 3371ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 337220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 33733b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 33746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 337520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 337620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 337720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 3378dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 33790024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 3380ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3381c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 3382c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3383ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 338448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 3385ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 3386ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 3387ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 3388ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 3389ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 3390ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 3391ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 3392ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 3393ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3394ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 339520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 339620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 3397dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 339820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 339918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 34003b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 34016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 34036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 34046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 34056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 34066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 34076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 34096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3411ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 34126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 34146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 34153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 34163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 34173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 34183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 34193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 34203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 34213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 34223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3423a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia CHECK(size >= 22); 34243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 34253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 34263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 34276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 342805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 342905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 343005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 343105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 343205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 343305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 343405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 343520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 343620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 343720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 343820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 343920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 344020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3441ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3442ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 344320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 344420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 344520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 34467b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 34477b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3448dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 344920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 345020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3451dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 345220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3453dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 345420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3455dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 345620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 345720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3458afd492436efc7f66b958da14659b52232efa5910Marco Nelissen int32_t tmp; 3459afd492436efc7f66b958da14659b52232efa5910Marco Nelissen CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp)); 3460afd492436efc7f66b958da14659b52232efa5910Marco Nelissen size_t max_size = tmp; 346120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3462afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // A somewhat arbitrary limit that should be sufficient for 8k video frames 3463afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // If you see the message below for a valid input stream: increase the limit 3464afd492436efc7f66b958da14659b52232efa5910Marco Nelissen if (max_size > 64 * 1024 * 1024) { 3465afd492436efc7f66b958da14659b52232efa5910Marco Nelissen ALOGE("bogus max input size: %zu", max_size); 3466afd492436efc7f66b958da14659b52232efa5910Marco Nelissen return ERROR_MALFORMED; 3467afd492436efc7f66b958da14659b52232efa5910Marco Nelissen } 3468afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = new MediaBufferGroup; 3469738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 34700024245e134467d120b40099da16c467dc365e76Andreas Huber 34718da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 34728da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 34738da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 3474afd492436efc7f66b958da14659b52232efa5910Marco Nelissen delete mGroup; 3475afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = NULL; 34768da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 34778da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 347820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 347920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 348020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 348120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 348220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 348320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 348420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 34857b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 34867b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3487dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 348820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 348920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 349020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 349120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 349220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 349320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34940024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 34950024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 34960024245e134467d120b40099da16c467dc365e76Andreas Huber 349720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 349820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 349920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 350020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 350120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 350220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 350320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 350420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 350520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 350605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 350705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 350805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 350905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 351005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 351105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 351205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 351305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 351405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 351605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 351705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 351805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 351905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 352005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 352105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 352305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 352405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 352505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 352705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 352805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 352905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 353205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 3533ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset); 353405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 353605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 353805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 354005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 354105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 354205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 354305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 354405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 354505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 354605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 354705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 35503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 35513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 35523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 35533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 35543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 35553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 35563f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 35573f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 35583f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 35593f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 35603f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 35613f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 35623f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 35633f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 356405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 356505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 356605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 356705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 356805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 356905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 357005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 357105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 357205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 357305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 357405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 357505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 357605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 357705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 357805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 357905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 358005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 358105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 358205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 358605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 358705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3589ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3590ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3591ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3592ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3593ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3594ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3595ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3596ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3597ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3598ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3599ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3600ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3601ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3602ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3603ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3604ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3605ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3606ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 3607ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 3608ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 3609ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 3610ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3611ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3612ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3613ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 362384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3624ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3625ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3626ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3627ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3628ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3629ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3630ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3631ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3632ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3633ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3634ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3635ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3636ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3637ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3638ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3639ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3640ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3641ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3642ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3643ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3644ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3645ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3646ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3647ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3648ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3649ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3650ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3651ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3652ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3653ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3654ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3655ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3656ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3657ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3658ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3659ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3660ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3661ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3662ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3663ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3664ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3665ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3666ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3667ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3668ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 366948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3670ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3671ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 367248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 367348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 367448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 367548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3676ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3677ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3678ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3679ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3680ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3681ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3682ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3683ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3684ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 368584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 368684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3687ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3688ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3689ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3690ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3691ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3692ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3693ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3694ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3695ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3696ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3697ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3698ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3699ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3700ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3701ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3702ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3703ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3704ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3705ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3706c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount == 0) { 3707c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 3708c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3709c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount > UINT32_MAX / 8) { 3710c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return ERROR_MALFORMED; 3711c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3712ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3713ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3714c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3715c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (newPtr == NULL) { 3716c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return NO_MEMORY; 3717c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3718c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia mCurrentSampleInfoOffsets = newPtr; 3719ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3720ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3721ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3722ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3723c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (mCurrentSampleInfoOffsets == NULL) { 3724c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 3725c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3726c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia 3727ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3728ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3729ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3730ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3731ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3732ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3736ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3737ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3738ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3739ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3740ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3741ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3742ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3743ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3745ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3746ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3748ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 375248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 3753529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen // only 0, 8 and 16 byte initialization vectors are supported 3754529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (ivlength != 0 && ivlength != 8 && ivlength != 16) { 3755529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("unsupported IV length: %d", ivlength); 3756529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen return ERROR_MALFORMED; 3757529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 375848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3759ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3760529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (i >= mCurrentSamples.size()) { 3761529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("too few samples"); 3762529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen break; 3763529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 3764ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3765ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3766ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3767ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3768ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3769ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3770ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3771ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3772ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 377348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 377448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 377548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3776ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 377748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 377848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 377948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3780ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3781ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3782ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 378348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 378448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 378548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 378648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 378748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 378848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 378948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 379048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 379148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 379248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 379348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 379448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 379548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3796ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 379748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 379848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 379948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3800ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3801ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3802ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3803ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3804ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3805ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3806ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 380705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 380805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 380905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 381005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 381105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 381205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 381305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3814ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 381505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 381605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 381705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 381805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 381905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 382005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 382105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 382205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 382305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 382405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 382505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 382605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 382705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 382805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 382905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 383005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 383105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 383205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 383305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 383405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 383505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 383605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 383705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 383805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 383905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 384005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 384105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 384305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 384405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 384505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 384705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 384805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 385005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 385105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 385205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 385305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 385405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 385505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 385605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 385705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 385805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 385905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 386005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 386105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 386205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 386305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 386405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 386505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 386605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 386705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 386805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 386905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 387005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 387105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 387205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 387305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 387505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 387605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 387705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 387805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 388005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 388105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 388205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 388305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 388405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 388505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 388605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 388705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 388805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 388905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 389005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 389105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 389205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 389305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 389405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 389505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 389605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 389705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 389805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 389905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 390005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 390305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 390405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 390905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 391705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 392505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 392705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 392905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 393005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 393105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 393305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 393405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 393505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 393605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 393805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 393905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 394005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 394105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 394205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 394705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 394905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 395005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 395105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 395405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 395505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 395605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 395905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 3985c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 3986c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 398705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 399005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 399105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 399205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 399305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 399405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 399505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 399605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 399905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 400005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 400105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 400205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 400305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 400405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 400505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 400605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 400805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 400905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 401005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 401105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 401205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4013ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar if (size < (off64_t)(sampleCount * bytesPerSample)) { 401405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 401505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 401905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 402005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 402105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 402205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 402305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 402405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 402505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 402705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 402805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 402905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 403105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 403405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 403505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 403605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 403805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 404105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 404205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 404305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 404505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4047a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 4048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 404905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 405005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 405105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 405205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 405305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 405405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 4055c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 405605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 405705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 405805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 405905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 406205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 406405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 406505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 40677b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 40687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 406920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 407020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 407120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 40736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 40746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 40756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 40766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 40776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 40786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 40796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 40806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 40816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 40826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 40836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 40846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 40856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 40866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 40876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 40886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 40896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 40906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 409120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 409220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 40937b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 40947b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 4095dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 409620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 409705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 409805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 409905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 410005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 410220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4103abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 4104abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 410520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 4106abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 4107abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 4108abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 4109abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 4110abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 4111abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4112abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4113abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 4114abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 4115abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4116abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 4117abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 4118abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 4119abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4120abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 4121abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 4122abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4123abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4124abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 412520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 4126abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 4127599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 4128abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 4129abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4130abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4131abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 4132abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 4133abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 4134abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4135abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4136abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4137abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 4138abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 4139abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 4140abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 4141abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 414220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4143788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 4144788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 4145788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 4146788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 4147788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 4148788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 414920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 41505295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 41515295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 41525295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 41535295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 41545295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 41555295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 41565295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 41575295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 415805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 415920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 416020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 416120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4162abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4163abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 4164abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4165abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4166abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 4167abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 4168abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 4169abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 4170abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4171df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 4172abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 4173abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 4174abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 4175abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 4176abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 4177abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4178abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 417920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 418020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 418120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 418220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 418320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 418420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 418520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 418620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4187c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 41880024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 4189170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 41908bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 4191dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 4192dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 4193dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 419420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4195c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 4196c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 4197170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 419820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4199dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4200dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4201dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4202dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4203dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 4204c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 4205dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4206ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 4207dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4208dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4209c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4210c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4211c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4212c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 42130024245e134467d120b40099da16c467dc365e76Andreas Huber } 421420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 4216dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 4217dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 421834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 4219dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4220dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 4221dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4222dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4223dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4224dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 4225dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4226dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 42277b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4228dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 4229dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 423048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 42314678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4232170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4233170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4234abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4235abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4236abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4237abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4238abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4239abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 42408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 42418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 42428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 42438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4244dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 4245dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4246dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 42473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 4248dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 4249dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4250dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4251dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4252dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4253dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4254dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 4255dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 4256dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 42576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 4258dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4259dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 4260dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 4261dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 42626064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 42635d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 42645d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 42655d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 42665d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 426729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 4268e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4269e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 4270e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 4271e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4272e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 4273e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 4274dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4275dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 42767b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 42776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 4278dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 42797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4280dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 42816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 42826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 4283dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4284dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 4285dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4286dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4287dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4288dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4289dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 4290dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4291dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4292dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 4293dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 4294dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 4295dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 4296dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 4297dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4298dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4299dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 4300dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 4301dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4302dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 4303dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 430420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 430520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 430620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 430720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 430820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4309dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 431020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 431120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4312dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4313dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4314dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 43156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 4316dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4317dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 4318dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 4319dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 4320e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4321dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 4322bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 432334fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 432434fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 432534fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 432634fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 4327bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength); 432834fe252c89e33572d01fea981b58d7b115e76164James Dong } 4329e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 433034fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 433129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 4332dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 4333dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 4334dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 4335dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4336dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 4337dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 4338dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 4339dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 434187afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 434287afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 434387afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 434487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size()); 434587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen android_errorWriteLog(0x534e4554, "27208621"); 434687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer->release(); 434787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer = NULL; 434887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen return ERROR_MALFORMED; 434987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen } 4350dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4351dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4352dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4353dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4354dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 4355dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 4356dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 4357dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 4358dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4359dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 4360dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4361dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 4362dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4363dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 436420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 436548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 43664678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4367170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4368170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4369abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4370abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4371abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4372abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4373abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4374abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 43758bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 43768bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 43778bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 43788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 437920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 438020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 438120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 438220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 438320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 438420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 438520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 438620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 438720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 438805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 438905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 439005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 439205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 439405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 439605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 439805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 440005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 440105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 440205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 440305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 440405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 440505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 440605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 440705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 440805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 440905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 441005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 44113f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 441205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 441305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 441405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 441505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 441605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 441705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 441805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 441905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 442005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 442105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 442205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 442305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4424ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 4425ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4426ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4427ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 4428ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 4429ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 4430ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 4431ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 4432ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4433ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4434ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 4435ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 4436ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 443705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 443805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 443905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 444005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 444105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 444205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 444405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 444505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 444705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4448442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 444905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 445005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 445105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 445205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 445305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 445405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 445505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 44563f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 44573f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 44583f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 44593f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4460ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 446105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 446205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 446305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 446405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 4465ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4466ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4467ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 446805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 446905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 447005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 447105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 447205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4473c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 447405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 447505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 447605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 447705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 447805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 447905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 448005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 448105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 448205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 448305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4484c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4485c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4486c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4487c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 448805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 448905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 449048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 449148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 449248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 449348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 449448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 449548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 449648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 449748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 449848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 449948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 450048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 450148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 450248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 450348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 450448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 45053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 450605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 4507da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (!isInRange((size_t)0u, mBuffer->size(), size)) { 4508da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4509da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4510da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 4511da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size); 4512da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4513da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4514da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 451505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 451605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 451705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 451805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 451905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 452005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 452105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4522da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 452305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 452405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 452505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 452605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 452705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 452805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 452905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4530170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4531170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 453205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 453305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 453405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 453505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 453605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 453705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 453805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 453905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 454005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 454105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 454205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 454305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 454405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 45453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 454605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 454705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 454805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 454905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 455005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 455105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 455205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 455305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 455405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 455505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 455605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 455705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 455805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 455905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 456005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 45615d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 45625d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 45635d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 45645d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen 45655d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 456605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 456705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 456805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 456905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 457005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 457105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 457205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 457305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 457405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 457505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 457605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 457705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 457805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 457905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 458005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 458105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 458205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 458305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 458405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 458505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 458605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 458705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 458805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 458905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 459005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 459105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 459205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 459305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 459405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 459505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 459605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 459705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4598da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih void *data = NULL; 4599da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih bool isMalFormed = false; 460005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 4601da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) { 4602da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 4603da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 4604da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mBuffer->data(); 4605da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 460605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 4607da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih int32_t max_size; 4608da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mFormat == NULL 4609da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !mFormat->findInt32(kKeyMaxInputSize, &max_size) 4610da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, (size_t)max_size, size)) { 4611da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 4612da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 4613da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mSrcBuffer; 4614da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 461505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 461605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4617da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (isMalFormed || data == NULL) { 4618da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("isMalFormed size %zu", size); 4619da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer != NULL) { 4620da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4621da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4622da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4623da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4624da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4625da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih num_bytes_read = mDataSource->readAt(offset, data, size); 4626da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 462705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 462805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 462905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 463005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4631da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 463205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 463305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 463405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 463505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 463605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 463705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 463805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 463905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 464005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 464105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 464205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 464305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 4645da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 464605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 464705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 464805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 464905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 4650da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength) 4651da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u) 4652da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength); 465305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 465405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 465505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 4656da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("Video is malformed; nalLength %zu", nalLength); 465705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 465805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 465905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 466005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 466105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 466205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 466305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 466405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 466505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 46665403587a74aee2fb57076528c3927851531c8afbMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 46675403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 46685403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 46695403587a74aee2fb57076528c3927851531c8afbMarco Nelissen ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size()); 46705403587a74aee2fb57076528c3927851531c8afbMarco Nelissen android_errorWriteLog(0x534e4554, "26365349"); 46715403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer->release(); 46725403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer = NULL; 46735403587a74aee2fb57076528c3927851531c8afbMarco Nelissen return ERROR_MALFORMED; 46745403587a74aee2fb57076528c3927851531c8afbMarco Nelissen } 467505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 467605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 467705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 467805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 467905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 468005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 468105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 468205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 468305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 468405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 468505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 468605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 468705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 468805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 468905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 469005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4691170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4692170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 469305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 469405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 469505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 469605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 469705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 469805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 469905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 470005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 470105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 470205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 470305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 470405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 470505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 470605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 470705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 470805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 470905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 471005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 471105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4712bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4713bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 4714bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4715bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 4716bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4717bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4718bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4719bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4720bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4721bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4722bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4723bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4724bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4725bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 47261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 472820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 472920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 473034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 473120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 473220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 473320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 473420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 473520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4736b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4737b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 47380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4739ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4740983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 474118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 47425a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 474320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 474420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 474520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 474620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 474720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 474820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 474920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 47511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 47521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 47531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 47541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 47553b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 47563b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 47571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 47581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 47591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 47604cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 47614cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 47624cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 47634cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 47644cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 476558fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 476658fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 476758fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 47681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 47691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 47701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 47711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 47721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 47731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 47741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 47751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 47761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 47771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 47781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 47791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 47801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 47811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 47821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4783a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4784a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4785a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 47861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4787a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4788a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4789a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4790a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 47911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4792a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4793a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4794a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4795a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 47961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4797a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4798a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4799a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4800a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4801a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4802a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4803a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4804a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4805a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4806a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4807a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4808a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 48091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 48101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4812a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4813a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4814a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4815a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4816a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4817a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4818a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4819452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 4820a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4821a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4822a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4823a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4824a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4825452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - offset) is either 8 or 16 4826452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset); 4827452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunkDataSize < 0) { 4828452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 4829452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 4830452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 4831a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 483205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 483305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 4834ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset); 4835a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4836a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4837a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4838a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4839a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4840a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4841a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4842a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4843a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4844a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4845a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4846a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4847a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4848a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4849a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4850a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4851a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4852a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4853a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4854a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4855a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4856a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4857a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4858a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4859a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4860a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4861a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4862a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4863a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4864a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4865a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4866a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4867a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 48681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 48691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4870a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4871a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4872a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4873a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4874a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4875a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4876a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4877a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4878a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4879a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4880a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 48811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4882a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4883a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 48841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4886a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 48871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 48881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 48915a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 48921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4893a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4894a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4895a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4896a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4897ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset); 4898a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4899a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 49001b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 49011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 49021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 49031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 49045a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4905a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4906a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 49071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 49081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 49101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 49115ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 49121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 49131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 49151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 49161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 49171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 491820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 4919