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 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 272377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 31018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 31318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 315371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 31618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 317371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 31918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 322e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 323e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 32418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 32718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3303b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 333dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 33948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 34048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 34148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 34348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 34448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 34548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 34648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 34848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 34948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 35048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 35148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 35248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 353693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 354c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 35505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 356bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3577be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 358fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 36072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 361dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 362dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 363dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 375dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 376dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 377dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 378dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 3798da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 380dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 381dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 382dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 383dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 384ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 385ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 386ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 387ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 39105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 39205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 39305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 39405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 39505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 3977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 3987be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 39972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4017be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 40272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 408ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 419a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 440371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 441371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 442371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 443371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 45105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 45205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 45305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 45405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 45505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 45605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 45705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 45805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 45905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 46005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 46105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 46205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 46305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 46405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 46505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 46605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 46705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 46805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 47748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 47848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 47948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 48048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 48148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 48248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 48348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 485bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 486bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 489c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 49105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (true) { 492a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 49305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 494a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 4954ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 4964ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 4974ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 498a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 499a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 500a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("did not advance: 0x%lld->0x%lld", orig_offset, offset); 501a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 502a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 503a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (err == OK) { 50405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 50505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 5064ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar 50705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 50805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(offset, hdr, 8) < 8) { 50905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 51005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 51105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 5123f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 51305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // store the offset of the first segment 51405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mMoofOffset = offset; 5153f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } else if (chunk_type != FOURCC('m', 'd', 'a', 't')) { 5163f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // keep parsing until we get to the data 5173f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen continue; 51805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 51905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5217be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 522bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 52372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 524bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 525bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 52672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 52772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 52872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 529bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 530bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 533bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 535ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 536ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int psshsize = 0; 537ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 538ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 540ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (psshsize) { 541ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 542ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 543ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 544ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 545ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 546ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 547ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 548ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 549ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 550ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 551bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 558dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 559dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 560dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 561dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 562dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 563dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 564dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 565dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 566dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 567dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 568dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 569dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 570dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 571dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 572dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 574dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 575dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 59384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 59484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t classSize = size; 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang classSize = size; 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 7058da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 7068da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 7078da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 7088da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 709f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 711f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 725dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 72772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 72872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 72972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 73072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 73172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 73272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 73472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 73572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 73672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 73872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 73972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 74072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 74172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 74272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 74372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 74472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 74572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 74672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 74772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 74872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 74972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 75072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 75172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 75372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 75472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 75572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 762c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 7635d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("entering parseChunk %lld/%d", *offset, depth); 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 76534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 770c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 77334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 77871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 77971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 78071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 78171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 78271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 783a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 784a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 785a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 786a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 787a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 788a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 789a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 790a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 791a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 792a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 793a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 794a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 795a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 796a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 797a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 798a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 79971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 80071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 801a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 80271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 80705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth); 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 812a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 815ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 816ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 817ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 818ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 819ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 820ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 821ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 823ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 824ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 82872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 829c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 832515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 83372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 834c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 83572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 83672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 83772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 83872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 83972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 84072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 84172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 842bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 843bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 844bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 845bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 84672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 84772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 84872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 84972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 86172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 86272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 863ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 864ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 8650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 86750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 868a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 86950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 870b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 871b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 872b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 87350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 87450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 87550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 87650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 87750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 87850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 87950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 8801edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 8811edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 88250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 88350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 8846f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 885bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 8866f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 8876f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 888bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 889bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 890bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 891bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 892bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 893bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 894bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 895bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 896bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 897bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 898bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 8996f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 900bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 901bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 902bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 903bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 904c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 915bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 916bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 9176f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 9186f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 9196f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 9206f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9216f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 9226f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 9236f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 9246f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 9256f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 9266f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 9276f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9286f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 9296f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 9306f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 9316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 9346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 936bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 937bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 938bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 939bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 940bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 941bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 942bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 94320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 944dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 945dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 946dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 947dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 948dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 94920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 9540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 9550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 9560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 9570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 9580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 9590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 9600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 9640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 9650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 9690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 9700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 971fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 972210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 9730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 9750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 9760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 9770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 9790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 9800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 9810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 9840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 9850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 9860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 9870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 9880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9890a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9900a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 9910a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 9920a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9950a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 996fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 997fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 998fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 9990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10000a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 10010a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 10021391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 10031391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 10041391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 10050a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 10060a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 10070a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10080a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 10090a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 10100a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10110a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingus = duration - (segment_duration + media_time); 1012465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1013465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1014465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1015465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1016465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1017465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 10180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 10190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 10200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 10230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 102948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 103648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 103748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 103848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 103948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 104048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 104148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10470517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1050ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1051ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1052ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1053ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1054ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1071ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1072ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1074ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 109620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 109720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 10980517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10990517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1100ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1101ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1102ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11100517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11110517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1116ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (pssh.datalen + 20 > chunk_size) { 1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1127ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11298da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 11308da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 11318da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 11328da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 114320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11450517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11460517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1147202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 114820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 114920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 115120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 115234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 115320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 115420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 115520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 115620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1158c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 115920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 116120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 116220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 116320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 116420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 116520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 116620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 116720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 116934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 117020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 117120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 117220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 117320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1177c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1178c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 117905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 118134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 118320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 118420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1186c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1187c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1188c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 119005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 119134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 119220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 119320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 119705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 119805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1200c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != 0) { 1201c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1202c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1203c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 12067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 12077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 12087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 12097a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 12107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 12117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 12127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 12167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 12177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 12217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 12227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 12237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 12247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 12257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 12267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 12277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 12287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 12307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 12317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1242c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1243bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1244bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1245bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 124634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 124720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 124820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 124920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 125320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 125420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 12593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 12603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 12613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1262ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 12633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 12643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1265ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1266ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 12673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 12683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 12693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 12703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 12713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1273c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1281bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1282bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1283bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1284bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 128520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 128620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 128948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1291371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 129220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 129320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 130120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 130548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 130881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 130981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 131048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 131148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 131248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 131348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 131420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 131548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 131681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 131720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 131820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 131920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1320c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 132120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 132220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 132620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1328bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1329bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1330bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1331bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 133320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1336ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 133720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1338e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1339e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 13413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 13423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 13447be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 13457be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1361ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1362a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1363a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1364a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1365a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1366a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1367a6256238d9015c42129fe43791968768fe501efaJames Dong 1368134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1369134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1371ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1372ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1373ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1374ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 137520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 137720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1378c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 137920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 138020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 138220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 138420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1386bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1387bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1388bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1389bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 139020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 139320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 139420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 139520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 139620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14000517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14010517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 140320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 141020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 141120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 141220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 141420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 141820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 141920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 142520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 143020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14310517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14320517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 143520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1437738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 143849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 143949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 144049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 144149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 144249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1443738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 144405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 144505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 144605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 144705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 144805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 144905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 145005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 145105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 145205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t width, height; 1453f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || 1454f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar !mLastTrack->meta->findInt32(kKeyHeight, &height)) { 145505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1456f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1457f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 145805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1459f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 14604256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 14614256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1462f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1463f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // AVC requires compression ratio of at least 2, and uses 1464f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1465f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1466f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1467f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1468f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1469f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 147005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1471f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 147205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1473113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 14744256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 14754256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1476113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1477113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1478113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1479113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1480113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1481113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1482113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1483113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1484113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1485113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1486113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1487113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1488113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1489113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1490113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 149120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 149220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 149320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 149420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 149520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 14960517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14970517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 149820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 150020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 150120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 150220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 150720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 150820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 15104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 15110517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15120517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 15134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 15144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 15154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 15164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 15184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 15194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15204931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15214931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 15224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 15260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 153020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 153720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15394948818cb91176df74c972ac27b2f392b5d148bcJames Dong // @xyz 15404948818cb91176df74c972ac27b2f392b5d148bcJames Dong case FOURCC('\xA9', 'x', 'y', 'z'): 15414948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 15420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15430517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 15444948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Best case the total data length inside "@xyz" box 15454948818cb91176df74c972ac27b2f392b5d148bcJames Dong // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 15464948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 15474948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 15484948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 15494948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 15504948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 15514948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15524948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15534948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 15544948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 15554948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 15564948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 15574948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15584948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 15594948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 15604948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 15614948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 15624948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 15634948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15644948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15654948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 15664948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 15674948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 15684948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15694948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15704948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 15714948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 15724948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 15734948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15744948818cb91176df74c972ac27b2f392b5d148bcJames Dong 157520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 157620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 15770517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15780517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 157920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 158020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1584c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 158520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 158620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 158920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 159020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 159120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 159220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 159320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 159420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 159520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 159620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 159720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 159820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 159920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 160020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1601ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1602ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1603ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1604ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1605ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1606ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1607ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1608ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1609ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1610ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1611ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1612ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1613ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1614ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1615ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 16210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1623d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 162420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 162534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1626d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 162720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 162820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 162920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1631d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 163220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 163420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 16363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 16373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 16383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 16393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 16403b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 16413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 16423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 16433b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 16443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 16453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 16463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 16473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 16483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 16493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 165020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1651244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1652244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 16530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 165417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 165517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 165617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 165717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 165817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 165917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 166017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 166117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 166217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 166317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 166417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 166517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 166617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 166717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 166829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1669244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1670244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1671244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1672244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1673244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1674244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1675244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1676244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1677244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1678244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1679244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1680244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1681244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 168272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 168372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 168472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1685c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 16860517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 1687bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1688bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1689bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 169072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 169172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 16920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 169372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 169472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 169572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 169672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 169772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1698ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1699ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1700ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1701ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1702ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1703ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1704ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 170572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 170672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1707c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 170872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 170972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 171072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 171172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 171272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 171372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 171472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1715bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1716bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1717bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1718bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 171972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 172072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 172172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 17225d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 17235d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 172472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 172572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 172872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1729fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 173072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 173172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 173272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 173372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 173472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 173572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 173672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 173772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 173872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 173972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 174072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17410517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1743c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 174472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 174572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 174672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1747c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 174872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 174972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 175072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 175172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 175272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 175372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1754fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 1755c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 175672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 175772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1758fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1759c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 1760c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1761c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1762c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1763bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1764bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 176572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 176672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1767fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 1768c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 1769c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1770c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1771c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1772c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1773c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1774c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != 0) { 1775c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 177672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 177772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 177872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 177972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 178072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 178172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 178272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 178372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 178472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 178572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1786c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 1787c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1788c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1789c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1790c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 1791c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1792c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1793c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1794c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 1795c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 1796c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 1797c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 1798c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1799c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1800c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1801c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 1802c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 1803c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 1804c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 1805c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1806c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1807c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 1808c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1809c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1810c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1811c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 1812c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 1813c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 1814c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 1815c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1816c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1817c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1818c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1819c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 1820c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1821c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1822c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1823c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != 0) { 1824c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 1825c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1826c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1827c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1828c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1829c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1830dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1831dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1832ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 1833dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1834dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1835dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1836dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1837dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1838dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1839dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1840dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1841dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1842dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1843dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1844dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 18453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 18463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 18470517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 18493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 18503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 18513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 18523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 18533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 18543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 18553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 18563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1857e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1858e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1859e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 18603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 18613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 18623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 18633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 18643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 18653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1866c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 1867c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1868c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1869c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1870c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 1871c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1872c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1873c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t duration; 1874c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 1875c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 1876c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 1877c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 1878c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 1879c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 1880c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1881c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1882c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 1883c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1884c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1885c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 18867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 18877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 18883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 18893b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 18903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 18913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 18923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 18933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 18943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 18953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 18968da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 18978da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 18988da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 18998da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 19003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 19023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 19033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 19063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 19073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 19083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 19093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19100517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 19110517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 19133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 19163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 19173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 19197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 19207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 19217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 19227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 19237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 1924515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 1925515e855eae78aa495da58356486aaa666cb57fd1James Dong { 19260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1928515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 19293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("chunk_data_size = %lld and data_offset = %lld", 1930515e855eae78aa495da58356486aaa666cb57fd1James Dong chunk_data_size, data_offset); 19311552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 1932515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 19331552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 1934515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 1935515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1936515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 1937515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 1938515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 19391552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1940515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1941515e855eae78aa495da58356486aaa666cb57fd1James Dong 1942515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 1943515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1944515e855eae78aa495da58356486aaa666cb57fd1James Dong 1945fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 1946fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 1947fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 1948fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 1949fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 1950fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 1951fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 19520517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1954fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 1955fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1956fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 1957fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 1958fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 1959fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1960fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 1961fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 1962fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1963328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 1964328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 19650517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19660517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1967328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 1968328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 1969328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 1970328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 1971328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 1972328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 1973328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 1974328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 1975328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 19765d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 19775d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 19785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 19795d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 19805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 19815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 19825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 19835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 19845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 198505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 198605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 198705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 198805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 198905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 199005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 199105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 199220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 199320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 199420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 199520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 199620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 199720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 199820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 199920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 200020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 200120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 200205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 200305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 200405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 200505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 200605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 200705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 200805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 200905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 201005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 201105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 201205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 201305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 201405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 201505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 201605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 201705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 201805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 201905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 202005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 202105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 202205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 202305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 202405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 202505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 202605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 202705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 202805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 202905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 203005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 203105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 203205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 203305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 203405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 203505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 203605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 203705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 203805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 203905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 204005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 204105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 204205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 204305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 204405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 204505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 204605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 204705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 204805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 204905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 205005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 205105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 205205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 205305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 205405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 205505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 205605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 205705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 205805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 205905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 206005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 206105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 206205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 206305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2064a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 206505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 206605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 206705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 206805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 206905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 207005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 207105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 207205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 207305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 207405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 207505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 207605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 207705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 207805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 207905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 208005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 208105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 208205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 208305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 208405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 208505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 208605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 208705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 208805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 208905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 209005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 209105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 209205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 209305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 209405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 209505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 20963f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 20973f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 20983f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 20993f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 210005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 210105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 210205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 210305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 210405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 210505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 210605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 210705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 210805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 210905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2110c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 211105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 211205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 211305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2114c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 211505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 211605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 211705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 211805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 211905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 212005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2121ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2122c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2123ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2124ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2125ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2126ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2127ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2128ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2129ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2130ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2131ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2132ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2133ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2134ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2135ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2136c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2137ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2138ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2139ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2140ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2141ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2142ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2143ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2144ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2145ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 2146ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2147ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2148ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2149ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2150ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2151ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2152ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 215304022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2154ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2155ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2156ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2157ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 215804022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 215904022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2160ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2161ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2162ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2163ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2164ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2165ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2166ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2167ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2168ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2169ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2170ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2171ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2172ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2173df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2174ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2175df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2176ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2177ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2178ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2179ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2180ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2181ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2182ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2183ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2184ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2185ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2186ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2187ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2188ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2189ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2190ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2191ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 21925ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2193ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2194ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2195ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2196ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2197ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2198ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2199ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2200b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2201b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2202ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2203ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2204b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2205b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2206ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2207ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2208ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2209ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2210fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 221172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 221272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 221372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 221472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 22158da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 22168da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 22178da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 22188da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 221972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 222072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 222172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 222272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 222372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 222472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 222572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 222672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 222772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 222872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 222972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 22305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 22315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 22325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("meta: %s @ %lld", chunk, offset); 223372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 223472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 223572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 223672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 223772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 223872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 223972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 224072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 224172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 224272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 224372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 224466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 224566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 224666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 224766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 224866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 224972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 225072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 225172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 225272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 225372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 225472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 225572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 225672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 225772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 225872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 225972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 226072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 226172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 226272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 226372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 226472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 226572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 226672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 226772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 226872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 226972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 227072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 227172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 227272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 227372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 227426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 227526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 227626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 227726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 227826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 227911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 228011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 228111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 228211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 228311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 228411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 228511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 228611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 228711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 228811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 228911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 229072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 229172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 229272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 229372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2294afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2295afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2296afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 229772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 229872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 229972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 230072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 230172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 230226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 230326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2304afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 230526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2306afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2307afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2308afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 230926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 231026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 231126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 231226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 231326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 23145d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 23155d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 23165d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 23175d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 23185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 23195d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 23205d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23215d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 23225d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 23235d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23245d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 23255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 23265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 23288c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 23298c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 23308c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 23318c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 23328c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 23338c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 23348c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 23358c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 23368c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 23378c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 23388c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 23398c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 23408c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 23418c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 23428c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 23438c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 23448c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 23458c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 23465d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 23478c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 23485d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 23495d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 23505d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 23515d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 23525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23535d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 235426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 235572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 235672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 235772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 235872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2359328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 236072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 236172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 236272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 236372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 236472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 236572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 236626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 236726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 236826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 236926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 237026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 237126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 237226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 237326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 237426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 237572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 237626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 237772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 237872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 237926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 238026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 238126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 238226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 238326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 238426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 238572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 238672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 238772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 238872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 238972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 239072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 239172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 239272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 239372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 239472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 239572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 239672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 239772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 239872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 239972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2400fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 2401fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size < 4) { 2402fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2403fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2404fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 24058da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size]; 24068da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 24078da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 24088da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 2409fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2410fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2411fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2412fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2413fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2414fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2415fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2416fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2417fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2418fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2419fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2420fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2421fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2422fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2423fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2424fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2425fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2426fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2427fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2428fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2429fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2430fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2431fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2432fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2433fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2434fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2435fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2436fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2437fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2438fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2439fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2440fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2441fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2442fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2443fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2444fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2445fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2446fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2447fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2448fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2449fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2450fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2451fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2452fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2453fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2454fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2455fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2456fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2457fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2458fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2459fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2460fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2461fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2462fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2463fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2464fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2465fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2466fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2467fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2468fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2469fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2470fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2471fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2472fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2473fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 2474fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2475fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2476fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2477fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2478fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2479fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2480fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2481fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2482fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2483fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2484fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2485fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2486fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2487fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2488fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2489fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2490fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2491fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2492fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2493fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2494fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2495fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2496fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 2497fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2498fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2499fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2500fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2501fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2502fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2503fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2504fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2505fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2506fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2507fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2508fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2509fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2510fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2511328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2512328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2513328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2514328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2515328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2516328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2517328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2518328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2519328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2520328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2521328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2522328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2523328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2524328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2525328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2526328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2527328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2528328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2529328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2530328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2531328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2532328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2533328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2534328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2535328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2536328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2537328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2538328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2539328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2540328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2541328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2542328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2543328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2544328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2545328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2546328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2547328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2548328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2549328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2550328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2551328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2552328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2553328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2554328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2555328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2556328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2557328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2558328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2559328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2560328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2561328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2562328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2563328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2564328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2565328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2566328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 256820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 256920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 257120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 257220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 257320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 257420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 257520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2576693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 257720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 257820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 257920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 258020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 258120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 258220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2583371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 2584371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 2585371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 2586371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2587c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2588c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 2589c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 2590c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 2591c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 2592c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *t = &mTrex.editItemAt(index); 2593c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 2594c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 2595c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2596c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2597c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2598c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2599c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2600a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 2601ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2602942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen return new MPEG4Source(this, 260305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 2604c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 260520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 260620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2607bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 2608bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 2609bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 2610bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2611bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2612bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 2613bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 2614bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 2615bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2616bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2617bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 2618bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2619bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 26203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 26213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 26223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 26233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 26243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 2625bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2626bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2627bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2628bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 2629bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2630bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2631bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2632bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2633ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 2634169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 2635ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 2636169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 2637169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 2638169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 2639bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 2640bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 2641bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2642f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 2643f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 2644f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 2645f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 2646f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 2647f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 2648f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 2649f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 2650f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 2651f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 2652f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 2653f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 2654f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 2655f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 2656f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 2657f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 2658f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 2659f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 2660f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 2661f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 2662f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 2663f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 2664f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 2665f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 2666f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 2667f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 2668f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 2669f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 2670f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 2671f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 2672f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 2673f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 2674f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 2675f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2676f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 2677f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2678f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 2679f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 2680f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 2681f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 2682f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 2683f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 2684f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 2685f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 2686f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2687f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 2688f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 2689f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 2690f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2691f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 2692f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 2693f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2694ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 2695ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 2696ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 269781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 269881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 269981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 270081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 270181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 270281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 270381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 270481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 270581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 270681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 270781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 270881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 2709633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 2710633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 2711633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 2712633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 271329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 2714633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 2715633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 2716633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 2717ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 2718ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 2719ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 2720ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 2721ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2722ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2723ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2724ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 2725ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 2726ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 2727ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 2728ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2729a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 2730a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 2731a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 2732a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 2733a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2734a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 2735a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 2736a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2737ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 2738ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2739ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2740ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 274100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 274200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 274300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 274400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 274500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 2746aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 2747aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 2748ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2749aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 2750aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 2751ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2752ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2753db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 2754db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 2755db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 2756aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 2757aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 2758ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 2759ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 2760ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 2761ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 2762ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2763ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2764aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 2765aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 2766ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 2767595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 276800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 276900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 277000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 2771ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2772ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 277300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 277400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 2775595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 2776f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 277700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 277800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent int32_t extSampleRate; 277900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 278000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 2781595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 2782595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 278300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 278400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 278500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 278600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 278700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 278800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 2789595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 279000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 279100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 2792ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2793ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2794f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 2795f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 2796f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 2797f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 2798f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 2799f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 2800f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 2801f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 2802f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 2803f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 2804f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2805f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 2806f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 2807f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2808f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 2809f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 2810f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 2811f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 2812f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2813f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 2814f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 2815f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2816f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2817f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 2818f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 2819f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 2820f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2821f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 2822f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 2823f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2824f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2825f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 2826f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 2827f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 2828f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t frameLengthFlag = br.getBits(1); 2829f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2830f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 2831f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2832f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 2833f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t coreCoderDelay = br.getBits(14); 2834f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2835f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 283645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 283745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 283845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 283945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 284045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 284145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 284245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 284345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 284445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 284545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 284645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 284745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 284845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 284945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 285045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 285145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 285245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih TRESPASS(); 285345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 285445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 285545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 285645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 285745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 2858f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 285945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 2860f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 2861f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 2862f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t ElementInstanceTag = br.getBits(4); 2863f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t Profile = br.getBits(2); 2864f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SamplingFrequencyIndex = br.getBits(4); 2865f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 2866f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 2867f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 2868f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 2869f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumAssocDataElements = br.getBits(3); 2870f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumValidCcElements = br.getBits(4); 2871f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2872f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 2873f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 2874f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownElementNumber = br.getBits(4); 2875f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2876f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2877f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 2878f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 2879f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownElementNumber = br.getBits(4); 2880f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2881f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2882f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 2883f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 2884f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndex = br.getBits(2); 2885f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t PseudoSurroundEnable = br.getBits(1); 2886f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2887f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2888f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 2889f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 2890f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 2891f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementTagSelect = br.getBits(4); 2892f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 2893f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2894f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2895f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 2896f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 2897f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementTagSelect = br.getBits(4); 2898f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 2899f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2900f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2901f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 2902f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 2903f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementTagSelect = br.getBits(4); 2904f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 2905f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2906f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 2907f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2908f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 2909f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t LfeElementTagSelect = br.getBits(4); 2910f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 2911f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2912f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 2913f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 2914f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 2915f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2916f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2917f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2918f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2919ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 2920ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 2921ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2922ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2923ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 2924ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 2925ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2926ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 29273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 2928ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 2929ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2930ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2931ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 2932ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2933ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 2934ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 2935ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2936ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 29373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 2938ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 2939ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2940ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2941ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 2942ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2943ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 2944ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 2945ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 294620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 294720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 294820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 2949942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 295020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 2951693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 295248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 295305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 295405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 2955c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 295605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 2957942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 2958942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 295920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 296048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 296120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 296220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 296305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 296405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 2965c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 296605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 296705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 296805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 2969ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 2970ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 2971ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 2972ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 297320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 29743b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 29756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 297620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 297720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 297820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 2979dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 29800024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 2981ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2982c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 2983c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2984ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 298548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 2986ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 2987ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 2988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 2989ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 2990ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 2991ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 2992ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 2993ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 2994ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2995ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 299620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 299720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 2998dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 299920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 300018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 30013b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 30026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 30046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 30056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 30066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 30076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 30086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 30106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3012ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 30136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 30146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 30156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 30163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 30173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 30183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 30193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 30203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 30213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 30223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 30233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 30243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 7); 30253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 30263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 30273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 30286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 302905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 303005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 303105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 303205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 303305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 303405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 303505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 303620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 303720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 303820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 303920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 304020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 304120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 304420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 304520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 304620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 30477b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 30487b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3049dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 305020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 305120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3052dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 305320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3054dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 305520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3056dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 305720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 305820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 305920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 306020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3061738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 3062738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 306320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3064738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 30650024245e134467d120b40099da16c467dc365e76Andreas Huber 30668da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 30678da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 30688da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 30698da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 30708da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 307120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 307220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 307320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 307420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 307520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 307620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 307720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 30787b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 30797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3080dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 308120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 308220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 308320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 308420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 308520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 308620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30870024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 30880024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 30890024245e134467d120b40099da16c467dc365e76Andreas Huber 309020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 309120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 309220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 309320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 309420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 309520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 309620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 309720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 309820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 309905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 310005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 310105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 310205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 310305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 310405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 310505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 310605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 310705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 310805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 310905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 311005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 311105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 311205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 311305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 311405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 311505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 311605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 311705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 311805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 311905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 312005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 312105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 312205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 312305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 312405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 312505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 312605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset); 312705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 312805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 312905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 313005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 313105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 313205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 313305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 313405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 313505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 313605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 313705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 313805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 313905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 314005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 314105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 314205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 31433f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 31443f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 31453f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 31463f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 31473f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 31483f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 31493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 31503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 31513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 31523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 31533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 31543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 31553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 31563f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 315705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 315805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 315905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 316005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 316105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 316205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 316305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 316405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 316505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 316605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 316705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 316805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 316905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 317005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 317105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 317205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 317305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 317405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 317505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 317605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 317705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 317805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 317905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 318005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 318105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3182ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3186ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3187ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3188ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3189ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3190ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3191ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3192ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3193ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3194ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3195ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3196ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3197ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3198ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 3200ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 3201ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 3202ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 3203ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3205ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3206ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 320705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 320805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 320905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 321005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 321105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 321205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 321305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 321405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 321584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 321684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3217ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3218ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3219ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3220ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3221ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3222ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3223ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3224ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3225ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3226ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3227ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3228ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3229ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3230ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3231ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3232ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3233ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3234ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3235ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3236ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3237ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3238ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3239ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3240ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3241ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3242ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3243ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3244ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3245ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3246ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3247ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3248ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3249ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3250ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3251ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3252ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3253ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3254ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3255ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3256ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3257ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3258ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3259ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3260ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3261ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 326248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3263ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3264ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 326548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 326648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 326748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 326848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3269ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3270ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3271ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3272ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3273ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3274ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3275ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3276ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3277ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 327884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 327984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3280ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3281ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3282ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3283ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3284ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3285ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3286ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3287ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3288ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3289ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3290ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3291ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3292ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3293ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3294ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3295ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3296ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3297ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3298ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3299ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3300ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3301ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3302ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3303ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3304ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3305ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3306ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3307ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3308ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3309ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3310ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3311ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3312ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3313ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3314ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3315ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3316ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3317ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3318ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3319ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3320ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3321ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3322ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3323ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3324ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3325ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3326ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3327ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3328ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3329ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3330ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 333148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 333248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3333ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3334ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3335ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3336ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3337ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3338ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3339ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3340ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3341ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3342ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 334348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 334448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 334548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3346ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 334748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 334848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 334948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3350ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3351ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3352ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 335348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 335448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 335548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 335648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 335748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 335848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 335948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 336048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 336148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 336248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 336348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 336448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 336548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3366ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 336748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 336848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 336948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3370ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3371ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3372ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3373ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3374ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3375ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3376ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 337705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 337805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 337905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 338005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 338105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 338205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 338305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3384ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 338505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 338605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 338705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 338805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 338905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 339005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 339205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 339305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 339405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 339605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 339705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 339805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 339905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 340005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 340105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 340205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 340305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 340405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 340505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 340605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 340705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 340805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 340905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 341005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 341105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 341305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 341405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 341505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 341705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 341805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 342005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 342105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 342205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 342305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 342405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 342505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 342605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 342705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 342805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 342905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 343005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 343105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 343205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 343305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 343405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 343505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 343605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 343705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 343805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 343905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 344005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 344105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 344205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 344305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 344405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 344505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 344605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 344705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 344805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 344905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 345005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 345105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 345205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 345305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 345405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 345505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 345705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 345805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 345905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 346005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 346205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 346305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 346405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 346505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 346605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 346705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 346905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 347005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 347105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 347205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 347305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 347405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 347505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 347605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 347705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 347805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 347905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 348005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 348105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 348205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 348305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 348405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 348505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 348605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 348705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 348805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 348905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 349005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 349105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 349205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 349305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 349405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 349505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 349605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 349705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 349805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 349905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 350005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 350105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 350205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 350305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 350405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 350505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 350605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 350705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 350805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 350905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 351005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 351105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 351205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 351305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 351505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 351705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 351905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 352005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 352105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 352405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 352505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 352605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 352905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 353105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 353205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 353505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 353605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 353705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 354005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 354105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 354305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 354405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 354605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 354705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 354805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 354905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 355005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 355105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 355205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 355305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 355405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 3555c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 3556c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 355705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 355805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 355905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 356005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 356105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 356205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 356305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 356405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 356505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 356605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 356705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 356805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 356905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 357005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 357105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 357205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 357305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 357405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 357505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 357605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 357705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 357805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 357905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 358005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 358105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3583a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn if (size < (off64_t)sampleCount * bytesPerSample) { 358405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 358505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 358805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 358905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 359005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 359105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 359205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 359305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 359405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 359505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 359705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 359805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 359905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 360105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 360405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 360505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 360605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 360805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 361105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 361205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 361305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3617a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 3618ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 362205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 3625c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 363005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 36377b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 36387b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 363920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 364020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 364120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 36436064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 36446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 36456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 36466064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 36476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 36486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 36496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 36506064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 36516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 36526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 36536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 36546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 36556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 36566064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 36576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 36586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 36596064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 36606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 366120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 366220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 36637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 36647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3665dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 366620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 367220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3673abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 3674abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 367520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 3676abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 3677abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3678abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 3679abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 3680abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 3681abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3682abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3683abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 3684abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 3685abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3686abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 3687abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 3688abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 3689abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3690abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 3691abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 3692abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3693abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3694abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 369520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 3696abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 3697599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 3698abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 3699abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3700abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3701abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 3702abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 3703abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 3704abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3705abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3706abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3707abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 3708abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 3709abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 3710abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 3711abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 371220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3713788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 3714788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 3715788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 3716788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 3717788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 3718788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 371920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 37205295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 37215295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 37225295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 37235295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 37245295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 37255295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 37265295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 37275295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 372805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 372920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 373020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 373120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3732abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3733abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 3734abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3735abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3736abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 3737abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 3738abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 3739abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 3740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3741df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 3742abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 3743abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 3744abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 3745abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 3746abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 3747abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 374920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 375020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 375120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 375220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 375320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 375420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 375520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 375620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3757c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 37580024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 3759170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 37608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 3761dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 3762dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 3763dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 376420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3765c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 3766c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 3767170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 376820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3769dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3770dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3771dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3772dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3773dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 3774c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 3775dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3776ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 3777dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3778dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 37790024245e134467d120b40099da16c467dc365e76Andreas Huber } 378020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 3782dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 3783dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 378434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 3785dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3786dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 3787dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3788dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3789dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3790dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 3791dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3792dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 37937b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3794dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 3795dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 379648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 37974678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3798170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 3799170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 3800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3802abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3803abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3804abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3805abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 38068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 38078bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 38088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 38098bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 3810dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 3811dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3812dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 3814dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 3815dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3817dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3818dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3819dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3820dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 3821dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 3822dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 3824dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3825dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 3826dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 3827dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 3829e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 383029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 3831e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3832e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 3833e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 3834e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3835e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 3836e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 3837dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 38397b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 38406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 3841dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 38427b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 38446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 38456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 3846dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3847dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 3848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3849dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3850dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3851dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3852dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 3853dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3854dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3855dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 3856dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 3857dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 3858dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 3859dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 3860dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 3861dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3862dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 3863dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 3864dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3865dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 3866dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 386720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 386820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 386920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 387020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 387120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 387320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 387420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3875dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3876dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3877dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 38786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 3879dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3880dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 3881dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 3882dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 3883e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3884dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 388534fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 388634fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 388734fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 388834fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 388934fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 389034fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 389134fe252c89e33572d01fea981b58d7b115e76164James Dong } 3892e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 389334fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 389429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 3895dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 3896dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 3897dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 3898dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3899dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 3900dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 3901dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 3902dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3904dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 3905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3906dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3907dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3908dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3909dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 3910dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 3911dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 3912dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 3913dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3914dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 3915dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3916dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 3917dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3918dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 391920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 392048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 39214678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3922170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 3923170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 3924abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3925abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3926abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3927abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3928abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3929abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 39308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 39318bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 39328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 39338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 393420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 393520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 393620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 393720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 393820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 393920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 394020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 394120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 394220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 394705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 394905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 395105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 395305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 395505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 395605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 395705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 395905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 396005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 39663f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 3979ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 3980ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 3981ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 3982ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 3983ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 3984ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 3985ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 3986ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 3987ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 3988ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 3989ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 3990ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 3991ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 399205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 399505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 399605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 399705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 400005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 400105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4003442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 400405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 400505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 400605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 400705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 400805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 400905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 401005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 40113f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 40123f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 40133f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 40143f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4015ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 401905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 4020ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4021ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4022ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 402305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 402405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 402605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 402705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4028c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 402905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 403005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 403105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 403305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 403505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 403605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 403705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 403805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 404248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 404348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 404448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 404548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 404648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 404748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 404848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 404948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 405048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 405148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 405248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 405348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 405448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 405548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 40563b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 405705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 405805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 405905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 406005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 406205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 406305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 406405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 406605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 406705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 407005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 407105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 407205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4073170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4074170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 407505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 407605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 407705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 407805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 407905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 408005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 408105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 408205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 408305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 408405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 408505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 408605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 408705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 40883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 408905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 409005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 409105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 409205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 409305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 409405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 409505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 409605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 409705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 409805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 409905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 410105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 410205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 410405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() < mNALLengthSize + nal_size) { 410505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 410605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 410805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 410905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 411005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 411105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 411305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 411405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 411505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 411605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 411705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 411805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 411905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 412005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 412105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 412205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 412305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 412405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 412505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 412605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 412705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 412805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 412905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 413005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 413105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 413205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 413305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 413405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 413505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 413605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 413705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 413805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = 413905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 414005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 414105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 414205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 414305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 414405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 414505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 414605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 414705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 414805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 414905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 415005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 415105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 415305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 415405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 415505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 415705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 415805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 415905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 416005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 416205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isMalFormed = (srcOffset + mNALLengthSize > size); 416305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 416405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 416505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 416605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 416705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isMalFormed = srcOffset + nalLength > size; 416805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 416905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 417005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 417105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("Video is malformed"); 417205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 417305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 417405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 417505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 417605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 417705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 417805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 417905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 418005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(dstOffset + 4 <= mBuffer->size()); 418205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 418405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 418505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 418605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 418705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 418805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 418905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 419005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 419105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 419205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 419305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 419405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 419505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 419705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4198170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4199170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 420005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 420105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 420205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 420305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 420405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 420505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 420605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 420705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 420805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 420905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 421005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 421105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 421205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 421305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 421405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 421505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 421605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 421705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 421805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4219bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4220bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 4221bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4222bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 4223bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4224bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4225bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4226bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4227bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4228bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4229bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4230bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4231bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4232bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 42331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4234693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 423520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 423620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 423734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 423820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 423920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 424020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 424120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 424220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4243b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4244b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 42450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4246ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4247983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 424818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 42495a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 425020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 425120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 425220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 425320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 425420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 425520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 425620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 42581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 42591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 42601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 42611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 42623b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 42633b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 42641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 42651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 42661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 42674cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 42684cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 42694cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 42704cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 42714cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 427258fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 427358fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 427458fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 42751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 42761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 42771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 42781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 42791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 42801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 42811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 42821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 42831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 42841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 42851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 42861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 42871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 42881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 42891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4290a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4291a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4292a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 42931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4294a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4295a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4296a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4297a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 42981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4299a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4300a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4301a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4302a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 43031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4304a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4305a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4306a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4307a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4308a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4309a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4310a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4311a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4312a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4313a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4314a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4315a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 43161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 43171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 43181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4319a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4320a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4321a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4322a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4323a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4324a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4325a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4326a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4327a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4328a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4329a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4330a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4331a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 4332a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 433305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 433405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 4335a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, offset); 4336a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4337a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4338a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4339a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4340a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4341a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4342a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4343a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4344a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4345a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4346a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4347a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4348a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4349a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4350a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4351a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4352a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4353a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4354a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4355a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4356a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4357a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4358a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4359a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4360a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4361a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4362a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4363a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4364a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4365a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4366a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4367a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4368a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 43691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 43701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4371a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4372a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4373a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4374a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4375a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4376a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4377a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4378a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4379a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4380a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4381a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 43821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4383a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4384a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 43851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 43861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4387a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 43881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 43891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 43901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 43911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 43925a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 43931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4394a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4395a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4396a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4397a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4398456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber ALOGV("found metadata size: %lld", moovAtomEndOffset); 4399a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4400a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 44011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 44021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 44031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 44055a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4406a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4407a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 44081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 44091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 44101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 44125ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 44131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 44141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 44151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 44161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 44171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 44181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 441920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 4420