MPEG4Extractor.cpp revision e3e82d54c51a3130badcd9e433fe808d965f15c2
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> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h> 44328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h" 45fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 51942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen MPEG4Source(const sp<MPEG4Extractor> &owner, 52942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MetaData> &format, 53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 5448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 5505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 5605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 57c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 5805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 6605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 70693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 727b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 737b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 74942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen // keep the MPEG4Extractor around, since we're referencing its data 75942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen sp<MPEG4Extractor> mOwner; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 77693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 79693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 8105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 8205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 83c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *mTrex; 8405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 8505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 8605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 8705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 8805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 8905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 92ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 93ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 94ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 95ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 9648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 97ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 98ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 99ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 1053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar bool mIsHEVC; 1066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 1076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1160024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1170024245e134467d120b40099da16c467dc365e76Andreas Huber 1186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 11905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 12005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 12105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 12405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 12505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 12605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 12705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 12805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 12905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 13305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 13405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 151c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t compositionOffset; 152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 173c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 174c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 177c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 186c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 221c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 233c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 241c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 268b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false; 269b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 274377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 31218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 31518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 317371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 31818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 319371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 32118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 324e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 325e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 32618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 32918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 335dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 34148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 34248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 34348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 34548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 34648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 34748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 34848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 35048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 35148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 35248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 35348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 35448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 355693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 356c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 357928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound(false), 358928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound(false), 35905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 360bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3617be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 362fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 36472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 365dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 366dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 367dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 379dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 380dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 381dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 382dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 3838da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 385dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 388ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 389ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 390ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 391ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 39505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 39605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 39705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 39805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 39905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 4017be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 4027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 40372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 40672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 412ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 423a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 444371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 445371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 446371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 447371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 45505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 45605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 45705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 45805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 45905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 46005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 46105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 46205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 46305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 46405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 46505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 46605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 46705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 46805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 46905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 47005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 47105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 48148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 48248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 48348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 48448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 48548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 48648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 48748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 489bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 490bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 493c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 495928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang bool sawMoovOrSidx = false; 496928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 497928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) { 498a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 49905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 500a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 5014ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 5024ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 5034ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 504a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 505a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 506a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("did not advance: 0x%lld->0x%lld", orig_offset, offset); 507a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 508a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 509928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } else if (err == UNKNOWN_ERROR) { 510928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang sawMoovOrSidx = true; 51105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 514bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 51572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 516bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 517bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 51872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 51972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 52072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 521bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 522bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 525bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 526ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 527ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 528ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int psshsize = 0; 529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 531ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 532ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (psshsize) { 533ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 535ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 536ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 537ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 538ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 540ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 541ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 542ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 543bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 558dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 559dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 560dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 561dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 562dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 563dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 564dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 566dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 567dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 568dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 569dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 570dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 571dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 572dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 573dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 574dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 575dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 58584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 58684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 6958da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 6968da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 6978da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 6988da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 699f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 701f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 71772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 71872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 71972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 72072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 72172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 72272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 72472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 72572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 72672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 72872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 72972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 73172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 73272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 73372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 73572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 73672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 73772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 73872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 73972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 74072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 74172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 74272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 74372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 74472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 74572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 74672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 74772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 74872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 74972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 75072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 75172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 752c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 7535d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("entering parseChunk %lld/%d", *offset, depth); 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 75534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 7592d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer int32_t chunk_type = ntohl(hdr[1]); 760c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 76334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 76871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 76971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 77071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 77171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 77271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 773a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 774a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 775a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 776a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 777a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 778a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 779a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 780a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 781a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 782a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 783a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 784a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 785a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 786a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 787a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 788a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 78971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 79071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 791a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 79271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 79705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth); 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 799b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 800b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe static const char kWhitespace[] = " "; 801b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 802b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 804b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe char buffer[256]; 805b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t n = chunk_size; 806b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (n > sizeof(buffer)) { 807b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe n = sizeof(buffer); 808b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 809b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (mDataSource->readAt(*offset, buffer, n) 810b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe < (ssize_t)n) { 811b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return ERROR_IO; 812b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 813ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 814b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(buffer, n); 815b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 81872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 819c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 822515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 82372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 824c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 82572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 82672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 82772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 82872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 82972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 83072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 83172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 832bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 833bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 834bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 835bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 83672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 83772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 83872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 83972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 85172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 85272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 853ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 854ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 8550a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 857928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) { 858928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang // store the offset of the first segment 859928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound = true; 860928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofOffset = *offset; 861928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } 862928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 86350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 864a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 86550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 866b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 867b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 868b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 86950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 87050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 87150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 87250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 87350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 87450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 87550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 8761edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 877f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 878f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 879f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 8801edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 88150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 88250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 8836f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 884bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 8856f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 8866f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 887bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 888bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 889bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 890bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 891bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 892bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 893bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 894bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 895bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 896bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 897bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 8986f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 899bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 900bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 901bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 902bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 903c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 912bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 915bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 9166f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 9176f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 9186f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 9196f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9206f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 9216f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 9226f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 9236f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 9246f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 9256f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 9266f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9276f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 9286f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 9296f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 9306f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 9336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 935bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 936bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 937bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 938bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 939bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 940bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 941bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 94220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 943dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 944dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 945dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 946dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 947dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 94820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 94920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 9530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 9540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 9550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 9560a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 9570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 9580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 9590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 9630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 9640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 9680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 9690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 970fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 971210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 9720a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 9740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 9750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 9760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 9780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 9790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 9800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 9830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 9840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 9850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 9860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 9870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9890a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 9900a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 9910a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9920a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 995fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 996fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 997fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 9980a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 10000a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 10011391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 10021391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 10031391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 10040a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 10050a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 10060a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10070a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 10080a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 10090a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10100a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingus = duration - (segment_duration + media_time); 1011465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1012465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1013465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1014465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1015465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1016465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 10170a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 10180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 10190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 10220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 102848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1034f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1035f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1036f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1037f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1038ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 103948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 104048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 104148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 104248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 104348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 104448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10500517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1052ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1053ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1054ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1071ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1072ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1074ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1093f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1094f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1095f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11040517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11050517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1106ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1107ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1108ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1127ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (pssh.datalen + 20 > chunk_size) { 1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11358da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 11368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 11378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 11388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 114920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 115020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11520517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1153202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 115420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 115520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 115720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 115834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 115920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 116020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 116120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 116220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 116320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1164c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 116520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 116720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 116920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 117020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 117120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 117220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 117320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 117534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 117720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 117920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1183c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1184c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 118505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 118734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1192c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1193c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1194c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 119605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 119734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 120020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 120120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 120305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 120405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 120520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1206e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mLastTrack->timescale != 0) { 1207c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1208c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1209c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 121020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 12127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 12137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 12147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 12157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 12167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 12177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 12187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 12227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 12237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 12277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 12287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 12297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 12307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 12317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 12327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 12337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 12347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 12367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 12377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1248c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1249bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1250bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1251bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 125234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 125320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 125420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 125520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 12653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 12663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 12673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1268ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 12693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 1270f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1271f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1272f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1273f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 12743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1275ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1276ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 12773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 12783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 12793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 12803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 12813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1283c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 128420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 128520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 128620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1291bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1292bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1293bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1294bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 129948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1301371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 131020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 131120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 131320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1314b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 131548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 131620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 131781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 131881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 131981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1320f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1321f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1322f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 132348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 132448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 132548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 132648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 132981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 133020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 133120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1333c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 133520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 133620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 133720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 133820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 133920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1341bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1342bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1343bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1344bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1349ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1351e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1352e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 13543b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 13553b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 13577be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 13587be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1370b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 137320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1374ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1375a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1376a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1377a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1378a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1379a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1380a6256238d9015c42129fe43791968768fe501efaJames Dong 1381134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1382134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1384f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1385f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1386f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1387ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1388ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1389ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1390ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 139320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1394c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 139520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 139620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1402bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1403bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1404bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1405bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 140620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 141020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 141120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1412274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1413274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1414274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 141620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 141820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 142120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1430274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1431274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1432274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 143520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 144720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 144820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1449274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1450274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1451274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 145220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 145520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14570517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1462738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 146349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 146449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 146549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 146649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 146749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1468738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 146905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 147005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 147105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 147205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 147305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 147405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 147505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 147605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 147705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t width, height; 1478f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || 1479f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar !mLastTrack->meta->findInt32(kKeyHeight, &height)) { 148005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1481f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1482f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 148305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1484f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 14854256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 14864256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1487f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1488f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // AVC requires compression ratio of at least 2, and uses 1489f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1490f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1491f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1492f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1493f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1494f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 149505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1496f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 149705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1498113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 14994256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 15004256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1501113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1502113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1503113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1504113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1505113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1506113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1507113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1508113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1509113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1510113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1511113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1512113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1513113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1514113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1515113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 151620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 152020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1521274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1522274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1523274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15240517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 152620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 153220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 153520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15374931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 15384931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 1539274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1540274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1541274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15430517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 15444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 15454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 15464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 15474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 15494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 15504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 15534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 155520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 155620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1557274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1558274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1559274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15610517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 156220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 156320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 156720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 156820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 156920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 157020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 157120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 157220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1573e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh // �xyz 1574e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh case FOURCC(0xA9, 'x', 'y', 'z'): 15754948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 15760517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15770517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1578e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh // Best case the total data length inside "�xyz" box 1579e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh // would be 8, for instance "�xyz" + "\x00\x04\x15\xc7" + "0+0/", 15804948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 15814948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 15824948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 15834948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 15844948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 15854948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15864948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15874948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 15884948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 15894948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 15904948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 15914948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15924948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 15934948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 15944948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 15954948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 15964948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 15974948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15984948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15994948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 16004948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 16014948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 16024948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16034948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16044948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 16054948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 16064948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 16074948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16084948818cb91176df74c972ac27b2f392b5d148bcJames Dong 160920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 161020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 16110517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16120517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 161320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 161420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 161520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1618c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 162120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 162234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 162320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 162420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 162520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 162720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 162820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 162920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 163020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 163120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1632f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1633f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1634f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 163520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 163620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 163720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1638ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1639ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1640ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1641ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1642ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1643ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1644ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1645ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1646ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1647ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1648ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1649ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1650ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1651ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1652ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 165320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 165420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 165520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 165720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 16580517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1660d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 166120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1663d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 166520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1667f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1668f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1669f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1671d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 167420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16753b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 16763b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 16773b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 16783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 16793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 16803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 16813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 16823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 16833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 1684f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1685f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1686f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 16873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 16883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 16893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 16903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 16913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 16923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 169320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1694244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1695244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 16960517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 169717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 169817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 169917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 170017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 170117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 170217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 170317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 170417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 170517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 170617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 170717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 170817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 170917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 171017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 171129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1712244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1713244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1714244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1715244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1716244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1717244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1718244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1719244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1720f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1721f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1722f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1723244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1724244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1725244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1726244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1727244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 172872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 172972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 173072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1731c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 17320517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 1733bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1734bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1735bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 173672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 173772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 17380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 173972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 174072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 174172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 174272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 174372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1744ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1745ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1746ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1747ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1748ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1749ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1750ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 175172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 175272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1753c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 175472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 175572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 175672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 175772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 175872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 175972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 176072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1761bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1762bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1763bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1764bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 176572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 176672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 176772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 17685d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 17695d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 177072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 177172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17720517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17730517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 177472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1775fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 177672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 177772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 177872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 177972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 178072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 178172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 178272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 178372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 178472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 178572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 178672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17870517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17880517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1789c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 179072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 179172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 179272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1793c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 179472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 179572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 179672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 179772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 179872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 179972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1800fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 1801c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 180272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 180372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1804fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1805c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 1806c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1807c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1808c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1809bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1810bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 181172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 181272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1813fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 1814c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 1815c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1816c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1817c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1818c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1819c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1820e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 1821c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 182272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 182372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 182472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 182572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 182672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 182772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 182872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 182972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 183072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 183172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1832c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 1833c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1834c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1835c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1836c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 1837c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1838c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1839c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1840c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 1841c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 1842c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 1843c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 1844c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1845c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1846c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1847c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 1848c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 1849c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 1850c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 1851c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1852c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1853c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 1854c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1855c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1856c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1857c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 1858c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 1859c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 1860c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 1861c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1862c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1863c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1864c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1865c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 1866c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1867c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1868c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1869e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 1870c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 1871c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1872c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1873c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1874c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1875c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1876dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1877dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1878ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 1879928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 1880928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound = true; 1881928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 1882dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1883dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1884dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1885dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1886dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1887dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1888dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1889dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1890dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1891dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1892dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1893dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 18943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 18953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 18960517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18970517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 18983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 18993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 19003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 19013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 19023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1904f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1905f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1906f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 19073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 19083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1909e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1910e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1911e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 19123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 19133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 19163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1918c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 1919c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1920c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1921c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1922c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 1923c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1924c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1925c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 1926c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 1927c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 1928c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 1929c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 1930c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 1931c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1932c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1933c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 1934c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1935c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1936c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 19377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 19387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 1939f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1940f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1941f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 19423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 19433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 19443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 19453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 19463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 19473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 19483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19508da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 19518da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 19528da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 19538da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 19543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 19563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 19573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 19603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 19613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 19623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 19633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19640517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 19650517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 19673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 19703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 19713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 19737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 19747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 19757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 19767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 19777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 1978515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 1979515e855eae78aa495da58356486aaa666cb57fd1James Dong { 19800517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19810517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1982515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 19833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("chunk_data_size = %lld and data_offset = %lld", 1984515e855eae78aa495da58356486aaa666cb57fd1James Dong chunk_data_size, data_offset); 19851552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 1986515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 19871552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 1988515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 1989515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1990515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 1991515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 1992515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 19931552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1994515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1995515e855eae78aa495da58356486aaa666cb57fd1James Dong 1996515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 1997515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1998515e855eae78aa495da58356486aaa666cb57fd1James Dong 1999fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2000fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2001fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2002fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2003fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2004fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2005fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 20060517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2008fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 2009fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2010fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 2011fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 2012fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2013fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2014fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2015fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2016fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2017328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 2018328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 20190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2021328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 2022328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 2023328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2024328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2025328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 2026328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2027328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 2028328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2029328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 20305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 20315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 20325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 20335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 20345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 20355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 20365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 20375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 20385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 203905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 204005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 204105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 204205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 204305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 204405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 204505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 204620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 204720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 204820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 204920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 205020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 205120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 205220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 205320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 205420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 205520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 205605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 205705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 205805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 205905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 206005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 206105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 206205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 206305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 206405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 206505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 206605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 206705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 206805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 206905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 207005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 207105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 207205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 207305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 207405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 207505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 207605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 207705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 207805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 207905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 208005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 208105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 208205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 2083e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (timeScale == 0) 2084e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake return ERROR_MALFORMED; 208505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 208605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 208705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 208805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 208905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 209005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 209105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 209205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 209305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 209405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 209505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 209605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 209705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 209805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 209905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 210005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 210105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 210205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 210305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 210405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 210505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 210605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 210705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 210805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 210905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 211005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 211105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 211205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 211305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 211405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 211505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 211605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 211705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 211805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 211905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2120a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 212105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 212205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 212305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 212405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 212505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 212605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 212705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 212805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 212905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 213005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 213105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 213205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 213305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 213405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 213505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 213605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 213705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 213805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 213905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 214005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 214105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 214205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 214305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 214405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 214505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 214605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 214705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 214805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 214905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 215005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 215105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 21523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 21533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 21543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 21553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 215605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 215705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 215805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 215905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 216005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 216105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 216205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 216305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 216405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 216505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2166c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 216705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2168f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2169f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2170f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 217105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 217205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2173c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 217405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 217505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 217605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 217705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 217805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 217905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2180ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2181c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2182ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2183ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2184ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2185ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2186ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2187ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2188ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2189ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2190ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2191ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2192ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2193ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2194ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2195c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2196ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2197ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2198ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2199ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2200ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2201ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2202ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2203ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2204b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint64_t ctime __unused, mtime __unused, duration __unused; 2205ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2206ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2207ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2208ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2209ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2210ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2211ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 221204022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2213ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2214ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2215ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2216ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 221704022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 221804022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2219ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2220ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2221f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2222f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2223f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2224ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2225ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2226ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2227ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2228ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2229ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2230ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2231ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2232ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2233b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2234b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2235b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 2236df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2237ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2238df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2239ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2240ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2241ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2242ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2243ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2244ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2245ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2246ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2247ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2248ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2249ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2250ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2251ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2252ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2253ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2254ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 22555ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2256ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2257ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2258ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2259ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2260ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2261ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2262ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2263b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2264b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2265ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2266ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2267b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2268b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2269ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2270ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2271ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2272ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2273fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 227472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 227572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 227672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 227772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 22788da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 22798da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 22808da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 22818da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 228272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 228372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 228472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 228572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 228672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 228772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 228872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 228972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 229072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 229172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 229272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 22935d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 22945d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 22955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("meta: %s @ %lld", chunk, offset); 22962d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer switch ((int32_t)mPath[4]) { 229772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 229872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 229972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 230072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 230172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 230272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 230372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 230472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 230572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 230672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 230766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 230866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 230966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 231066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 231166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 231272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 231372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 231472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 231572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 231672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 231772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 231872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 231972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 232072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 232172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 232272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 232372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 232472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 232572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 232672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 232772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 232872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 232972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 233072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 233172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 233272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 233372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 233472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 233572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 233672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 233726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 233826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 233926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 234026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 234126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 234211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 234311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 234411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 234511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 234611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 234711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 234811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 234911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 235011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 235111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 235211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 235372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 235472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 235572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 235672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2357afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2358afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2359afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 236072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 236172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 236272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 236372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 236472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 236526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 236626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2367afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 236826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2369afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2370afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2371afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 237226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 237326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 237426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 237526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 237626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 23775d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 23785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 23795d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 23805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 23815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 23825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 23835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 23855d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 23865d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23875d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 23885d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 23895d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23905d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 23918c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 23928c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 23938c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 23948c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 23958c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 23968c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 23978c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 23988c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 23998c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 24008c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 24018c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 24028c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 24038c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 24048c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 24058c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 2406f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2407f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2408f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 24098c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 24108c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 24118c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 24125d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 24138c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 24145d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 24155d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 24165d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 24175d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 24185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 24195d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 242026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 242172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 242272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 242372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 242472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2425328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 242672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 242772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 242872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 242972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 243072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 243172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 243226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 243326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 243426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 243526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 243626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 243726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 243826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 243926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 244026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 244172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 244226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 244372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 244472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 244526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 244626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 244726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 244826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 244926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 245026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 245172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 245272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 245372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 245472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 245572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 245672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 245772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 245872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 245972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 246072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 246172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 246272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 246372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 246472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 246572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2466fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 2467fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size < 4) { 2468fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2469fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2470fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 24718da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size]; 24728da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 24738da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 24748da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 2475fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2476fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2477fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2478fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2479fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2480fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2481fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2482fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2483fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2484fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2485fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2486fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2487fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2488fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2489fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2490fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2491fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2492fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2493fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2494fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2495fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2496fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2497fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2498fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2499fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2500fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2501fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2502fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2503fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2504fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2505fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2506fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2507fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2508fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2509fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2510fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2511fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2512fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2513fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2514fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2515fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2516fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2517fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2518fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2519fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2520fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2521fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2522fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2523fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2524fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2525fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2526fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2527fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2528fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2529fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2530fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2531fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2532fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2533fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2534fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2535fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2536fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2537fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2538fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2539fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 2540fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2541fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2542fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2543fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2544fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2545fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2546fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2547fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2548fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2549fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2550fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2551fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2552fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2553fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2554fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2555fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2556fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2557fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2558fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2559fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2560fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2561fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2562fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 2563fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2564fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2565fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2566fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2567fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2568fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2569fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2570fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2571fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2572fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2573fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2574fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2575fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2576fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2577328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2578328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2579328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2580328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2581328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2582328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2583328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2584328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2585328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2586328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2587328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2588328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2589328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2590328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2591328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2592328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2593328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2594328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2595328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2596328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2597328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2598328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2599328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2600328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2601328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2602328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2603328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2604328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2605328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2606328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2607328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2608328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2609328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2610328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2611328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2612328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2613328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2614328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2615328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2616328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2617328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2618328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2619328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2620328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2621328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2622328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2623328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2624328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2625328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2626328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2627328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2628328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2629328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2630328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2631328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2632328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 263420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 263520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 263720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 263820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 263920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 264020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 264120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 264320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 264420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 264520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 264620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 264720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 264820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2649371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 2650371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 2651371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 2652371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2653c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2654c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 2655c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 2656c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 2657c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 2658c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *t = &mTrex.editItemAt(index); 2659c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 2660c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 2661c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2662c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2663c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2664c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2665c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2666a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 2667ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2668942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen return new MPEG4Source(this, 266905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 2670c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 267120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 267220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2673bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 2674bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 2675bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 2676bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2677bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2678bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 2679bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 2680bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 2681bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2682bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2683bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 2684bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2685bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 26863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 26873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 26883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 26893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 26903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 2691bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2692bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2693bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2694bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 2695bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2696bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2697bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2698bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2699ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 2700169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 2701ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 2702169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 2703169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 2704169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 2705bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 2706bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 2707bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2708f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 2709f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 2710f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 2711f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 2712f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 2713f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 2714f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 2715f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 2716f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 2717f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 2718f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 2719f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 2720f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 2721f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 2722f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 2723f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 2724f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 2725f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 2726f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 2727f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 2728f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 2729f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 2730f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 2731f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 2732f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 2733f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 2734f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 2735f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 2736f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 2737f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 2738f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 2739f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 2740f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 2741f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2742f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 2743f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2744f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 2745f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 2746f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 2747f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 2748f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 2749f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 2750f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 2751f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 2752f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2753f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 2754f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 2755f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 2756f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2757f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 2758f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 2759f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2760ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 2761ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 2762ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 276381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 276481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 276581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 276681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 276781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 276881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 276981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 277081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 2771f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2772f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2773f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 277481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 277581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 277681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 277781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 2778633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 2779633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 2780633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 2781633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 278229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 2783633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 2784633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 2785633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 2786ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 2787ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 2788ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 2789ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 2790ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2791ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2792ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2793b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 2794b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("ESD of size %d\n", csd_size); 2795b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(csd, csd_size); 2796b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 2797ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2798a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 2799a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 2800a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 2801a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 2802a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2803a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 2804a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 2805a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2806ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 2807ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2808ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2809ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 281000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 281100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 281200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 281300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 281400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 2815aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 2816aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 2817ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2818aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 2819aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 2820ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2821ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2822f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2823f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2824f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2825db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 2826db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 2827db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 2828aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 2829aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 2830ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 2831ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 2832ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 2833ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 2834ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2835ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2836aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 2837aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 2838ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 2839595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 284000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 284100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 284200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 2843ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2844ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 284500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 284600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 2847595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 2848f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 284900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 2850b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t extSampleRate __unused; 285100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 285200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 2853595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 2854595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 285500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 285600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 285700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 285800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 285900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 286000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 2861595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 286200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 286300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 2864ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2865ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2866f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 2867f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 2868f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 2869f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 2870f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 2871f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 2872f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 2873f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 2874f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 2875f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 2876f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2877f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 2878f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 2879f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2880f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 2881f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 2882f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 2883f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 2884f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2885f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 2886f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 2887f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2888f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2889f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 2890f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 2891f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 2892f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2893f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 2894f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 2895f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2896f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2897f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 2898f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 2899f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 2900b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t frameLengthFlag __unused = br.getBits(1); 2901f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2902f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 2903f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2904f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 2905b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t coreCoderDelay __unused = br.getBits(14); 2906f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2907f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 290845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 290945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 291045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 291145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 291245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 291345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 291445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 291545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 291645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 291745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 291845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 291945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 292045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 292145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 292245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 292345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 292445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih TRESPASS(); 292545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 292645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 292745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 292845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 292945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 2930f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 293145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 2932f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 2933f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 2934b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t ElementInstanceTag __unused = br.getBits(4); 2935b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t Profile __unused = br.getBits(2); 2936b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SamplingFrequencyIndex __unused = br.getBits(4); 2937f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 2938f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 2939f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 2940f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 2941b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumAssocDataElements __unused = br.getBits(3); 2942b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumValidCcElements __unused = br.getBits(4); 2943f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2944f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 2945f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 2946b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MonoMixdownElementNumber __unused = br.getBits(4); 2947f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2948f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2949f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 2950f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 2951b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t StereoMixdownElementNumber __unused = br.getBits(4); 2952f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2953f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2954f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 2955f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 2956b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MatrixMixdownIndex __unused = br.getBits(2); 2957b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t PseudoSurroundEnable __unused = br.getBits(1); 2958f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2959f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2960f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 2961f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 2962f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 2963b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t FrontElementTagSelect __unused = br.getBits(4); 2964f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 2965f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2966f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2967f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 2968f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 2969b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SideElementTagSelect __unused = br.getBits(4); 2970f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 2971f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2972f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2973f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 2974f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 2975b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t BackElementTagSelect __unused = br.getBits(4); 2976f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 2977f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2978f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 2979f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2980f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 2981b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t LfeElementTagSelect __unused = br.getBits(4); 2982f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 2983f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2984f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 2985f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 2986f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 2987f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2988f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2989f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2990f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2991ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 2992ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 2993ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2994ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2995f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2996f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2997f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2998ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 2999ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 3000ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3001ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 30023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 3003ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 3004ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3005ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3006ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 3007ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3008ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 3009ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 3010ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3011ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 30123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 3013ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 3014ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3015ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3016ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 3017ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3018ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 3019ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 3020ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 302120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 302220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 302320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 3024942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 302520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 3026693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 302748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 302805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 302905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 3030c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 303105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 3032942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 3033942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 303420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 303548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 303620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 303720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 303805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 303905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 3040c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 304105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 304205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 304305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 3044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 3045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 3046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 3047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 304820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 30493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 30506064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 305120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 305220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 305320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 3054dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 30550024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 3056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3057c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 3058c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 306048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 3061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 3062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 3063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 3064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 3065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 3066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 3067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 3068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 3069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 307120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 307220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 3073dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 307420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 307518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 30763b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 30776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 30796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 30806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 30816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 30826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 30836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 30856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3087ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 30886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 30906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 30913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 30923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 30933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 30943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 30953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 30963b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 30973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 30983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 30993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 7); 31003b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 31013b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 31023b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 31036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 310405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 310505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 310605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 310705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 310805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 310905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 311005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 311120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 311220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 311320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 311420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 311520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 311620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 311920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 312020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 312120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 31227b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 31237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3124dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 312520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 312620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3127dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 312820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3129dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 313020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3131dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 313220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 313320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 313420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 313520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3136738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 3137738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 313820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3139738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 31400024245e134467d120b40099da16c467dc365e76Andreas Huber 31418da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 31428da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 31438da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 31448da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 31458da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 314620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 314720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 314820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 314920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 315020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 315120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 315220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 31537b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 31547b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3155dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 315620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 315720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 315820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 315920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 316020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 316120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31620024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 31630024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 31640024245e134467d120b40099da16c467dc365e76Andreas Huber 316520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 316620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 316720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 316820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 316920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 317020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 317120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 317220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 317320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 317405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 317505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 317605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 317705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 317805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 317905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 318005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 318105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 318205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 318305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 318405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 318505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 318605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 318705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 318805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 318905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 319005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 319105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 319205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 319305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 319405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 319505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 319605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 319705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 319805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 319905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 320005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 320105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset); 320205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 320305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 320405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 320505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 320605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 320705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 320805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 320905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 321005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 321105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 321205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 321305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 321405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 321505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 321605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 321705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 32183f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 32193f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 32203f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 32213f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 32223f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 32233f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 32243f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 32253f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 32263f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 32273f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 32283f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 32293f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 32303f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 32313f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 323205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 323305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 323405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 323505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 323605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 323705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 323805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 323905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 324005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 324105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 324205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 324305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 324405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 324505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 324605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 324705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 324805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 324905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 325005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 325105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 325205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 325305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 325405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 325505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 325605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3257ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3258ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3259ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3260ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3261ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3262ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3263ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3264ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3265ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3266ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3267ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3268ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3269ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3270ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3271ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3272ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3273ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3274ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 3275ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 3276ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 3277ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 3278ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3279ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3280ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3281ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 328205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 328305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 328405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 328505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 328605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 328705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 328805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 328905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 329084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 329184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3292ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3293ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3294ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3295ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3296ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3297ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3298ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3299ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3300ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3301ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3302ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3303ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3304ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3305ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3306ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3307ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3308ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3309ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3310ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3311ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3312ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3313ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3314ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3315ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3316ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3317ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3318ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3319ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3320ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3321ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3322ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3323ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3324ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3325ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3326ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3327ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3328ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3329ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3330ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3331ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3332ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3333ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3334ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3335ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3336ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 333748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3338ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3339ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 334048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 334148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 334248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 334348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3344ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3345ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3346ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3347ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3348ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3349ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3350ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3351ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3352ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 335384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 335484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3355ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3356ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3357ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3358ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3359ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3360ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3361ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3362ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3363ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3364ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3365ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3366ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3367ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3368ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3369ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3370ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3371ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3372ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3373ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3374ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3375ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3376ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3377ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3378ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3379ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3380ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3381ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3382ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3383ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3384ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3385ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3386ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3387ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3388ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3389ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3390ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3391ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3392ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3393ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3394ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3395ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3396ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3397ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3398ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3399ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3400ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3401ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3402ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3403ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3404ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3405ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 340648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 340748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3408ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3409ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3410ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3411ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3412ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3413ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3414ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3415ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3416ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3417ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 341848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 341948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 342048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3421ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 342248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 342348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 342448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3425ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3426ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3427ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 342848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 342948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 343048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 343148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 343248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 343348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 343448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 343548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 343648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 343748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 343848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 343948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 344048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3441ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 344248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 344348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 344448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3445ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3446ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3447ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3448ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3449ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3450ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3451ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 345205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 345305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 345505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 345605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 345705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3459ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 346005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 346105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 346205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 346405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 346505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 346605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 346805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 346905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 347005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 347105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 347205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 347305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 347405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 347505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 347605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 347705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 347805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 347905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 348005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 348105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 348205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 348305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 348405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 348505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 348605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 348705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 348805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 348905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 349005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 349105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 349205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 349305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 349405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 349505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 349605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 349705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 349805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 349905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 350005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 350105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 350205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 350305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 350405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 350505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 350605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 350705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 350805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 350905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 351005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 351105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 351305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 351405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 351505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 351605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 351705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 351805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 352005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 352105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 352205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 352505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 352605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 352805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 352905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 353205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 353305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 353405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 353705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 353805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 354005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 354105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 354305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 354405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 354505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 354705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 354805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 354905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 355005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 355105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 355205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 355305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 355405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 355505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 355605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 355705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 355805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 355905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 356005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 356105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 356205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 356305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 356405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 356505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 356605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 356705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 356805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 356905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 357005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 357105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 357205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 357305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 357405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 357505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 357605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 357705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 357805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 357905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 358005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 358305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 358405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 358505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 358705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 358805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 359005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 359205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 359405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 359505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 359605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 359705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 359905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 360005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 360105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 360405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 360605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 360705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 361005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 361105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 361205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 362205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 362505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 3630c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 3631c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 363605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 363705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 363805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 363905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 364005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 364105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 364205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 364405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 364505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 364605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 364705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 364805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 364905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 365005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 365205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 365305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 365405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 365505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 365605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3658a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn if (size < (off64_t)sampleCount * bytesPerSample) { 365905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 366005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 366205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 366305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 366405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 366505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 366605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 367205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 367305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 367405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 367605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 367905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 368105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 368305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 368605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 368705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 368805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 369005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3692a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 3693ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 369405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 369505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 369605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 369705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 369805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 369905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 3700c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 370105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 370205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 370405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 370505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 370705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 370905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 371005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 371120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 37127b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 37137b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 371420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 371520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 371620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 37186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 37196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 37206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 37216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 37226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 37236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 37246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 37256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 37266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 37276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 37286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 37296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 37306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 37316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 37326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 37336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 37346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 37356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 373620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 373720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 37387b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 37397b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3740dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 374120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 374205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 374305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 374405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 374505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 374620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 374720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 3749abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 375020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 3751abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 3752abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3753abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 3754abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 3755abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 3756abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3757abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3758abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 3759abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 3760abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3761abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 3762abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 3763abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 3764abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3765abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 3766abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 3767abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3768abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3769abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 377020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 3771abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 3772599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 3773abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 3774abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3775abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3776abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 3777abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 3778abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 3779abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3780abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3781abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3782abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 3783abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 3784abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 3785abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 3786abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 378720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3788788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 3789788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 3790788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 3791788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 3792788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 3793788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 379420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 37955295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 37965295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 37975295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 37985295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 37995295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 38005295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 38015295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 38025295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 380305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 380420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 380520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 380620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3807abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3808abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 3809abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3810abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3811abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 3812abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 3813abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 3814abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 3815abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3816df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 3817abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 3818abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 3819abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 3820abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 3821abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 3822abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3823abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 382420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 382520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 382620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 382720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 382820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 382920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 383020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 383120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3832c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 38330024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 3834170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 38358bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 3836dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 3837dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 3838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 383920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3840c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 3841c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 3842170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 384320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3846dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3847dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 3849c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 3850dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3851ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 3852dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3853dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 38540024245e134467d120b40099da16c467dc365e76Andreas Huber } 385520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38563b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 3857dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 3858dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 385934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 3860dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3861dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 3862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3863dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3864dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 3866dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3867dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 3870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 387148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 38724678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3873170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 3874170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 3875abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3876abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3877abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3878abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3879abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3880abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 38818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 38828bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 38838bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 38848bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 3885dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 3886dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3887dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 3889dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 3890dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3891dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3893dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3894dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3895dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 3896dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 3897dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 3899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 3901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 3902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 39036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 3904e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 390529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 3906e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3907e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 3908e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 3909e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3910e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 3911e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 3912dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3913dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 39147b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 39156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 3916dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 39177b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3918dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 39196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 39206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 3921dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3922dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 3923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3924dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3925dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3926dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3927dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 3928dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3929dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3930dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 3931dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 3932dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 3933dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 3934dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 3935dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 3936dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3937dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 3938dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 3939dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3940dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 3941dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 394220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 394320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 394420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 394520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 394620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 394820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 394920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3950dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3951dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3952dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 39536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 3954dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3955dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 3956dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 3957dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 3958e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3959dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 396034fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 396134fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 396234fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 396334fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 396434fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 396534fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 396634fe252c89e33572d01fea981b58d7b115e76164James Dong } 3967e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 396834fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 396929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 3970dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 3971dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 3972dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 3973dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3974dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 3975dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 3976dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 3977dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3978dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3979dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 3980dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3981dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3982dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3983dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3984dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 3985dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 3986dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 3987dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 3988dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3989dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 3990dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3991dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 3992dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3993dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 399420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 399548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 39964678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3997170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 3998170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 3999abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4000abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4001abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4002abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4003abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4004abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 40058bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 40068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 40078bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 40088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 400920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 401020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 401220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 401320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 401520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 401620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 401720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 401905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 402005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 402205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 402405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 402605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 402805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 403005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 403105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 403205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 403405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 403505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 403605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 403705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 403805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 403905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 404005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 40413f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 404205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 404305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 404405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 404505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 404605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 404705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 404805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 405005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 405105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 405205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 405305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4054ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 4055ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4056ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4057ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 4058ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 4059ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 4060ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 4061ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 4062ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4063ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4064ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 4065ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 4066ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 406705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 407005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 407105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 407205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 407305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 407405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 407505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 407605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 407705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4078442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 407905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 408005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 408105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 408205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 408305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 408405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 408505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 40863f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 40873f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 40883f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 40893f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4090ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 409105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 409205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 409305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 409405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 4095ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4096ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4097ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 409805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 409905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 410105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 410205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4103c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 410405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 410505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 410605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 410805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 411005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 411105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 411205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 411305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 411648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 411748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 411848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 411948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 412048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 412148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 412248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 412348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 412448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 412548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 412648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 412748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 412848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 412948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 413048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 41313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 413205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 413305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 413405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 413505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 413605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 413705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 413805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 413905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 414005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 414105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 414205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 414305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 414405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 414505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 414605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 414705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4148170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4149170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 415005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 415205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 415305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 415405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 415505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 415705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 415805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 415905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 416105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 416205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 41633b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 416405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 416505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 416605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 416805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 416905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 417005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 417105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 417205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 417305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 417405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 417505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 417605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 417705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 417805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 417905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() < mNALLengthSize + nal_size) { 418005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 418105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 418305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 418405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 418605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 418705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 418905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 419005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 419105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 419305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 419405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 419505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 419605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 419805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 419905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 420005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 420105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 420205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 420305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 420405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 420505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 420605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 420705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 420805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 420905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 421005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 421105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 421205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 421305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = 421405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 421505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 421605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 421705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 421805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 421905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 422005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 422105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 422205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 422305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 422405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 422505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 422605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 422705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 422805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 422905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 423005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 423105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 423205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 423305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 423405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 423505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 423605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 423705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isMalFormed = (srcOffset + mNALLengthSize > size); 423805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 423905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 424005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 424105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 424205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isMalFormed = srcOffset + nalLength > size; 424305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 424405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 424505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 424605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("Video is malformed"); 424705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 424805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 424905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 425005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 425105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 425205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 425305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 425405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 425505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 425605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(dstOffset + 4 <= mBuffer->size()); 425705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 425805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 425905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 426005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 426105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 426205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 426305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 426405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 426505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 426605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 426705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 426805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 426905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 427005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 427205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4273170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4274170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 427505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 427705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 427805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 427905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 428005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 428105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 428205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 428305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 428405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 428505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 428605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 428705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 428805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 428905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 429005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 429105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 429205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 429305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4294bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4295bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 4296bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4297bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 4298bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4299bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4300bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4301bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4302bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4303bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4304bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4305bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4306bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4307bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 43081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 431020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 431120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 431234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 431320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 431420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 431520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 431620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 431720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4318b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4319b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 43200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4321ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4322983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 432318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 43245a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 432520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 432620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 432720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 432820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 432920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 433020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 433120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43321b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 43331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 43341b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 43351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 43361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 43373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 43383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 43391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 43401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 43411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 43424cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 43434cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 43444cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 43454cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 43464cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 434758fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 434858fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 434958fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 43501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 43511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 43521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 43531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 43541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 43551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 43561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 43571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 43581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 43591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 43601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 43611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 43621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 43631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 43641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4365a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4366a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4367a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 43681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4369a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4370a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4371a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4372a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 43731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4374a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4375a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4376a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4377a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 43781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4379a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4380a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4381a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4382a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4383a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4384a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4385a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4386a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4387a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4388a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4389a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4390a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 43911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 43921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 43931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4394a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4395a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4396a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4397a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4398a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4399a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4400a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4401a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4402a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4403a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4404a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4405a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4406a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 4407a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 440805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 440905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 4410a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, offset); 4411a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4412a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4413a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4414a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4415a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4416a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4417a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4418a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4419a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4420a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4421a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4422a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4423a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4424a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4425a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4426a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4427a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4428a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4429a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4430a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4431a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4432a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4433a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4434a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4435a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4436a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4437a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4438a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4439a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4440a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4441a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4442a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4443a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 44441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 44451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4446a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4447a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4448a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4449a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4450a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4451a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4452a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4453a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4454a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4455a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4456a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 44571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4458a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4459a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 44601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 44611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4462a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 44631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 44641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 44651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 44675a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 44681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4469a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4470a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4471a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4472a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4473456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber ALOGV("found metadata size: %lld", moovAtomEndOffset); 4474a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4475a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 44761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 44771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 44781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 44805a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4481a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4482a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 44831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 44841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 44851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 44875ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 44881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 44891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 44901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 44921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 44931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 449420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 4495