MPEG4Extractor.cpp revision 635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951c
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen//#define LOG_NDEBUG 0 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1989e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <utils/Log.h> 27a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 28a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/MPEG4Extractor.h" 29a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/SampleTable.h" 30a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/ESDS.h" 31a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ABitReader.h> 33d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson#include <media/stagefright/foundation/ABuffer.h> 34ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 35a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h> 44328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h" 45fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 51942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen MPEG4Source(const sp<MPEG4Extractor> &owner, 52942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MetaData> &format, 53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 5448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 5505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 5605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 57c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 5805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 6605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 70693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 727b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 737b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 74942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen // keep the MPEG4Extractor around, since we're referencing its data 75942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen sp<MPEG4Extractor> mOwner; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 77693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 79693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 8105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 8205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 83c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *mTrex; 8405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 8505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 8605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 8705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 8805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 8905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 92ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 93ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 94ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 95ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 9648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 97ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 98ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 99ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 1053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar bool mIsHEVC; 1066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 1076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1160024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1170024245e134467d120b40099da16c467dc365e76Andreas Huber 1186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 11905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 12005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 12105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 12405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 12505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 12605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 12705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 12805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 12905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 13305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 13405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 151c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t compositionOffset; 152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 173c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 174c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 177c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 186c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 221c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 233c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 241c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 268b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false; 269b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 274377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 31218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 31518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 317371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 31818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 319371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 32118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 324e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 325e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 32618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 32918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 335dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 34148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 34248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 34348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 34548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 34648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 34748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 34848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 34948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 35048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 35148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 35248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 35348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 35448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 355693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 356c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 357928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound(false), 358928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound(false), 35905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 360bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3617be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 362fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 36472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 365dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 366dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 367dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 379dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 380dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 381dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 382dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 3838da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 385dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 388ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 389ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 390ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 391ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 39505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 39605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 39705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 39805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 39905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 4017be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 4027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 40372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 40672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 412ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 423a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 444371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 445371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 446371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 447371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 45505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 45605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 45705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 45805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 45905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 46005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 46105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 46205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 46305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 46405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 46505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 46605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 46705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 46805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 46905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 47005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 47105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 48148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 48248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 48348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 48448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 48548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 48648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 48748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 489bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 490bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 493c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 495928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang bool sawMoovOrSidx = false; 496928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 497928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) { 498a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 49905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 500a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 5014ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 5024ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 5034ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 504a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 505a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 506ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset); 507a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 508a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 509928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } else if (err == UNKNOWN_ERROR) { 510928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang sawMoovOrSidx = true; 51105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 514bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 51572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 516bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 517bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 51872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 51972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 52072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 521bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 522bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 525bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 526ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 527ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 528ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int psshsize = 0; 529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 531ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 532ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (psshsize) { 533ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 535ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 536ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 537ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 538ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 540ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 541ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 542ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 543bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 558dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 559dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 560dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 561dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 562dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 563dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 564dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 566dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 567dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 568dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 569dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 570dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 571dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 572dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 573dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 574dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 575dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 58584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 58684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 6958da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 6968da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 6978da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 6988da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 699f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 701f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 71772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 71872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 71972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 72072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 72172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 72272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 72472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 72572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 72672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 72872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 72972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 73172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 73272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 73372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 73572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 73672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 73772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 73872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 73972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 74072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 74172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 7428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) { 7438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return path.size() >= 2 7448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[0] == FOURCC('m', 'o', 'o', 'v') 7458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[1] == FOURCC('m', 'e', 't', 'a') 7468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && (depth == 2 7478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || (depth == 3 748ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang && (path[2] == FOURCC('h', 'd', 'l', 'r') 749ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang || path[2] == FOURCC('i', 'l', 's', 't') 7508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || path[2] == FOURCC('k', 'e', 'y', 's')))); 7518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 7528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 75372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 75472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 75572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 75672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 763c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 764ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth); 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 76634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 7702d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer int32_t chunk_type = ntohl(hdr[1]); 771c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 77434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 77971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 78071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 78171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 78271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 78371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 784a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 785a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 786a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 787a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 788a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 789a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 790a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 791a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 792a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 793a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 794a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 795a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 796a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 797a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 798a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 799a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 80071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 80171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 802a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 80371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 808ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth); 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 810b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 811b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe static const char kWhitespace[] = " "; 812b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 813b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 815b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe char buffer[256]; 816b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t n = chunk_size; 817b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (n > sizeof(buffer)) { 818b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe n = sizeof(buffer); 819b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 820b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (mDataSource->readAt(*offset, buffer, n) 821b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe < (ssize_t)n) { 822b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return ERROR_IO; 823b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 824ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 825b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(buffer, n); 826b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 82972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 830c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 833515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 83472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 835c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 83672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 83772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 83872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 83972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 84072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 84172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 84272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 843bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 844bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 845bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 846bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 84772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 84872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 84972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 85072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 86120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 86272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 86372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 864ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 865ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 8660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 868928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) { 869928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang // store the offset of the first segment 870928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound = true; 871928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofOffset = *offset; 872928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } 873928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 87450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 875a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 87650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 877b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 878b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 879b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 88050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 88150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 88250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 88350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 88450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 88550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 88650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 8871edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 888f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 889f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 890f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 8911edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 89250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 89350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 8946f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 895bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 8966f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 8976f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 898bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 899bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 900bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 901bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 902bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 903bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 904bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 905bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 906bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 907bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 908bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 9096f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 910bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 911bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 912bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 914c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 923bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 924bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 925bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 926bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 9276f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 9286f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 9296f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 9306f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 9326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 9336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 9346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 9356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 9366f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 9376f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9386f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 9396f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 9406f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 9416f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 9446f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 946bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 947bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 948bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 949bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 950bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 951bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 952bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 95320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 954dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 955dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 956dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 957dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 958dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 9640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 9650517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 9660517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 9670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 9680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 9690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 9700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9710a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9720a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 9740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 9750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 9790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 9800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 981fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 982210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 9830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 9850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 9860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 9870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 9890a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 9900a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 9910a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9920a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 9940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 9950a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 9960a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 9970a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 9980a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10000a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 10010a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 10020a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10030a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10040a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10050a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1006fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 1007fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 1008fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 10090a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10100a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 10110a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 10121391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 10131391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 10141391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 10150a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 10160a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 10170a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 10190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 10200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingus = duration - (segment_duration + media_time); 1022465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1023465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1024465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1025465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1026465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1027465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 10280a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 10290a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 10300a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10310a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10320a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 10330a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10340a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1036ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 103948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1045f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1046f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1047f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1048f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 105048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 105148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 105248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 105348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 105448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 105548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10610517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10620517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1071ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1072ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1074ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1104f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1105f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1106f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1117ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1118ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1119ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (pssh.datalen + 20 > chunk_size) { 1142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11468da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 11478da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 11488da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 11498da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 116020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 116120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11620517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11630517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1164202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 116520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 116620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 116720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 116934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 117020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 117120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 117220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 117320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1175c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 117920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 118320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 118634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 118720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11922e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (!timescale) { 11932e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale should not be ZERO."); 11942e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 11952e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 11962e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 119720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1199c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1200c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 120105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 120220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 120334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 120520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 120620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 120720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1208c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1209c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1210c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 121120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 121205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 121334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 121620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 121720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 121905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 122005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 122120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1222e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mLastTrack->timescale != 0) { 1223c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1224c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1225c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 12287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 12297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 12307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 12317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 12327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 12337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 12347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 12387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 12397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 12437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 12447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 12457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 12467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 12477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 12487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 12497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 12507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 12527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 12537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 125420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 125520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1264c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1265bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1266bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1267bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 126834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 12813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 12823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 12833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1284ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 12853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 1286f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1287f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1288f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1289f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 12903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1291ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1292ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 12933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 12943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 12953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 12963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 12973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1299c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 130120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1307bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1308bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1309bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1310bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 131120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 131320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 131420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 131548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 131620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1317371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 131820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 131920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 132020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 132120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 132220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 132534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 132620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 132820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1330b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 133148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 133481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 133581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1336f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1337f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1338f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 133948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 134048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 134148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 134248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 134581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1349c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1357bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1358bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1359bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1360bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1365ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1367e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1368e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 136920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 13703b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 13713b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 13737be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 13747be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 137520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 137720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 137820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 137920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 138134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 138220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 138420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1386b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 138720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 138820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1390ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1391a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1392a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1393a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1394a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1395a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1396a6256238d9015c42129fe43791968768fe501efaJames Dong 1397134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1398134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1400f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1401f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1402f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1403ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1404ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1405ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1406ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1410c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 141120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 141220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 141420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 141620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1418bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1419bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1420bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1421bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1428274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1429274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1430274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 143220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14350517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14360517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1446274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1447274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1448274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 145020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 145120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 145220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 145520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 145620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 145720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1465274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1466274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1467274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 146820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 146920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14720517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14730517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 147420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 147520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1478738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 147949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 148049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 148149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 148249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 148349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1484738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 148505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 148605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 148705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 148805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 148905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 149005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 149105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 149205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 149305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t width, height; 1494f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || 1495f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar !mLastTrack->meta->findInt32(kKeyHeight, &height)) { 149605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1497f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1498f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 149905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1500f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 15014256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 15024256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1503f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1504f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // AVC requires compression ratio of at least 2, and uses 1505f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1506f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1507f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1508f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1509f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1510f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 151105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1512f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 151305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1514113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 15154256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 15164256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1517113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1518113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1519113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1520113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1521113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1522113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1523113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1524113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1525113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1526113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1527113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1528113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1529113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1530113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1531113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 153220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 153620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1537274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1538274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1539274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15400517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15410517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 154220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 154320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 154420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 154520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 154620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 154720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 154920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 155020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 155120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 155220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 15544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 1555274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1556274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1557274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15580517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 15604931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 15614931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 15624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 15634931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 15654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 15664931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 15684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 15694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 15704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 157120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 157220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1573274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1574274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1575274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 15760517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15770517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 157820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 157920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 158020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 158420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 158720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1589e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh // �xyz 1590e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh case FOURCC(0xA9, 'x', 'y', 'z'): 15914948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 15920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15930517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1594e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh // Best case the total data length inside "�xyz" box 1595e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh // would be 8, for instance "�xyz" + "\x00\x04\x15\xc7" + "0+0/", 15964948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 15974948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 15984948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 15994948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 16004948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16014948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16024948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16034948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 16044948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 16054948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 16064948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 16074948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16084948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 16094948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 16104948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 16114948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 16124948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16134948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16144948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16154948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 16164948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 16174948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 16184948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16194948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16204948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 16214948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 16224948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 16234948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16244948818cb91176df74c972ac27b2f392b5d148bcJames Dong 162520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 16270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 162920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 163020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 163120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 163220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1634c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 163520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 163620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 163720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 163920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 164020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 164120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 164220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 164420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 164520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 164620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1648f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1649f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1650f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 165120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 165220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 165320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1654ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1655ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1656ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1657ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1658ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1659ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1660ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1661ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1662ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1663ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1664ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1665ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1666ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1667ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1668ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 167120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 16740517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16750517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1676d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 167720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1679d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 168020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 168120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 168220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1683f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1684f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1685f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 168620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1687d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 168820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 168920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 169020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 16923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 16933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 16943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 16953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 16963b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 16973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 16983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 16993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 1700f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1701f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1702f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 17033b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 17043b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 17053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 17063b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 17073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 17083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 170920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1710244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1711244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 17120517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 171317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 171417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 171517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 171617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 171717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 171817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 171917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 172017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 172117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 172217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 172317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 172417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 172517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 172617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1727ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size); 1728244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1729244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1730244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1731244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1732244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1733244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1734244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1735244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1736f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1737f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1738f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1739244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1740244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1741244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1742244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1743244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 174472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 174572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stop_offset = *offset + chunk_size; 17478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset = data_offset; 17488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang bool isParsingMetaKeys = underQTMetaPath(mPath, 2); 17498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!isParsingMetaKeys) { 17508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint8_t buffer[4]; 17518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (chunk_data_size < (off64_t)sizeof(buffer)) { 17528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 17538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 17548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 1755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 17568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 17578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang data_offset, buffer, 4) < 4) { 17588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 17598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_IO; 17608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 176172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 17628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (U32_AT(buffer) != 0) { 17638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // Should be version 0, flags 0. 1764ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 17658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // If it's not, let's assume this is one of those 17668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // apparently malformed chunks that don't have flags 17678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // and completely different semantics than what's 17688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // in the MPEG4 specs and skip it. 17698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 17708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 17718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 17728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += sizeof(buffer); 177372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 177472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 177572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 177672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 177772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 177872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 177972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 178072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1781bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1782bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1783bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1784bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 178572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 178672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 178772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 17885d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 17895d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 179072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 179172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 17920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17930517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 179472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1795fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 179672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 179772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 179872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 179972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 180072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 180172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 180272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 180372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 180472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 180572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 180672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 18070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1809c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 181072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 181172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 181272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1813c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 181472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 181572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 181672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 181772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 181872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 181972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1820fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 1821c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 182272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 182372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1824fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1825c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 1826c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1827c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1828c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1829bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1830bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 183172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 183272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1833fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 1834c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 1835c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1836c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1837c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1838c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1839c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1840e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 1841c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 184272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 184372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 184472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 184572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 184672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 184772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 184872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 184972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 185072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 185172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1852c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 1853c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1854c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1855c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1856c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 1857c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1858c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1859c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1860c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 1861c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 1862c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 1863c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 1864c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1865c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1866c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1867c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 1868c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 1869c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 1870c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 1871c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1872c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1873c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 1874c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1875c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1876c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1877c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 1878c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 1879c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 1880c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 1881c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1882c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1883c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1884c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1885c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 1886c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1887c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1888c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1889e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 1890c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 1891c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1892c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1893c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1894c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1895c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1896dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1897dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1898ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 1899928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 1900928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound = true; 1901928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 1902dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1903dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1904dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1905dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1906dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1907dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1908dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1909dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1910dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1911dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1912dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1913dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 19143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 19153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 19160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1918ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang if (underQTMetaPath(mPath, 3)) { 1919ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang break; 1920ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang } 1921ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang 19223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 19233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 19243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 19253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 19263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1928f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1929f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1930f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 19313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 19323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1933e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1934e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1935e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 19363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 19373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 19403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang case FOURCC('k', 'e', 'y', 's'): 19438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang { 19448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 19458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 19468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 19478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaKey(data_offset, chunk_data_size); 19488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 19498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang break; 19508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 19518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 1952c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 1953c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1954c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1955c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1956c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 1957c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1958c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1959c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 1960c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 1961c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 1962c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 1963c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 1964c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 1965c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1966c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1967c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 1968c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 1969c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1970c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 19717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 19727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 1973f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1974f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1975f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 19763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 19773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 19783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 19793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 19803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 19813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 19823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 1984dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake if (SIZE_MAX - chunk_size <= size) { 1985dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake return ERROR_MALFORMED; 1986dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake } 1987dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake 19888da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 19898da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 19908da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 19918da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 19923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 19943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 19953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 19963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 19973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 19983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 19993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 20003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 20013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20020517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 20030517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 20053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 20083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 20093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 20117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 20127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 20137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 20147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 20157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 2016515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 2017515e855eae78aa495da58356486aaa666cb57fd1James Dong { 20180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2020515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 2021635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, 2022635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert chunk_data_size, data_offset); 20231e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake 2024635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) { 20251e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake return ERROR_MALFORMED; 20261e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake } 20271552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 2028515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 20291552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 2030515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 2031515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2032515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 203397d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake if (chunk_data_size <= kSkipBytesOfDataBox) { 203497d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake return ERROR_MALFORMED; 203597d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake } 203697d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake 2037515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 2038515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 20391552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 2040515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2041515e855eae78aa495da58356486aaa666cb57fd1James Dong 2042515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 2043515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2044515e855eae78aa495da58356486aaa666cb57fd1James Dong 2045fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2046fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2047fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2048fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2049fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2050fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2051fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 20520517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2054fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 2055fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2056fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 2057fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 2058fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2059fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2060fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2061fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2062fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2063328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 2064328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 20650517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20660517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2067328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 2068328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 2069328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2070328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2071328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 2072328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2073328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 2074328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2075328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 20765d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 20775d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 20785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 20795d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 20805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 20815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 20825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 20835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 20845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 208505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 208605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 208705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 208805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 208905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 209005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 209105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 209220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 209320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 20948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // check if we're parsing 'ilst' for meta keys 20958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // if so, treat type as a number (key-id). 20968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 20978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaVal(chunk_type, data_offset, chunk_data_size); 20988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 20998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 210020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 210120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 210220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 210320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 210420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 210520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 210620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 210720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 210805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 210905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 211005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 211105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 211205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 211305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 211405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 211505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 211605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 211705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 211805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 211905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 212005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 212105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 212205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 212305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 212405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 212505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 212605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 212705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 212805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 212905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 213005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 213105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 213205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 213305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 213405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 2135e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (timeScale == 0) 2136e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake return ERROR_MALFORMED; 213705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 213805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 213905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 214005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 214105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 214205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 214305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 214405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 214505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 214605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 214705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 214805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 214905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 215005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 215105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 215205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 215305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 215405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 215505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 215605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 215705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 215805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 215905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 216005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 216105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 216205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 216305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 216405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 216505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 216605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 216705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 216805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 216905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 217005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 217105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2172a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 217305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 217405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 217505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 217605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 217705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 217805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 217905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 218005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 218105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 218205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 218305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 218405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 218505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 218605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 218705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 218805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 218905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 219005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 219105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 219205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 219305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 219405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 219505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 219605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 219705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 219805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 219905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 220005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 220105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 220205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 220305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 22043f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 22053f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 22063f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 22073f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 220805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 220905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 221005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 221105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 221205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 221305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 221405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 221505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 221605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 221705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2218c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 221905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2220f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2221f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2222f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 222305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 222405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2225c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 222605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 222705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 222805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 222905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 22308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) { 22318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size < 8) { 22328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t count; 22368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &count)) { 22378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mMetaKeyMap.size() > 0) { 22418cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGW("'keys' atom seen again, discarding existing entries"); 22428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.clear(); 22438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t keyOffset = offset + 8; 22468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stopOffset = offset + size; 22478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang for (size_t i = 1; i <= count; i++) { 22488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyOffset + 8 > stopOffset) { 22498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t keySize; 22538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset, &keySize) 22548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keySize < 8 22558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keyOffset + keySize > stopOffset) { 22568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t type; 22608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset + 4, &type) 22618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || type != FOURCC('m', 'd', 't', 'a')) { 22628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keySize -= 8; 22668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += 8; 22678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang sp<ABuffer> keyData = new ABuffer(keySize); 22698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyData->data() == NULL) { 22708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 22738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset, keyData->data(), keySize) < (ssize_t) keySize) { 22748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang AString key((const char *)keyData->data(), keySize); 22788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.add(i, key); 22798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += keySize; 22818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 22838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 22848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 22858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal( 22868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang int32_t keyId, off64_t offset, size_t size) { 22878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ssize_t index = mMetaKeyMap.indexOfKey(keyId); 22888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (index < 0) { 22898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // corresponding key is not present, ignore 22908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 229205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 22938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size <= 16) { 22948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 22958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataSize; 22978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &dataSize) 22988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || dataSize > size || dataSize <= 16) { 22998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t atomFourCC; 23028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &atomFourCC) 23038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || atomFourCC != FOURCC('d', 'a', 't', 'a')) { 23048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataType; 23078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 8, &dataType) 23088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || ((dataType & 0xff000000) != 0)) { 23098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // not well-known type 23108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang dataSize -= 16; 23148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang offset += 16; 23158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (dataType == 23 && dataSize >= 4) { 23178cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // BE Float32 23188cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t val; 23198cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &val)) { 23208cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23218cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) { 23238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val); 23248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } else { 23268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // add more keys if needed 23278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGV("ignoring key: type %d, size %d", dataType, dataSize); 23288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 23318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 233205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2333ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2334c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2335ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2336ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2337ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2338ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2339ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2340ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2341ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2342ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2343ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2344ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2345ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2346ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2347ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2348c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2349ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2350ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2351ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2352ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2353ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2354ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2355ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2356ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2357b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint64_t ctime __unused, mtime __unused, duration __unused; 2358ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2359ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2360ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2361ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2362ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2363ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2364ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 236504022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2366ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2367ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2368ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2369ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 237004022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 237104022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2372ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2373ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2374f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2375f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2376f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2377ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2378ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2379ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2380ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2381ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2382ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2383ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2384ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2385ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2386b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2387b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2388b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 2389df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2390ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2391df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2392ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2393ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2394ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2395ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2396ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2397ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2398ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2399ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2400ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2401ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2402ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2403ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2404ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2405ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2406ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2407ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 24085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2409ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2410ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2411ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2412ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2413ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2414ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2415ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2416b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2417b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2418ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2419ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2420b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2421b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2422ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2423ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2424ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2425ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2426fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 242772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 242872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 242972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 243072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 24318da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 24328da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 24338da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 24348da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 243572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 243672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 243772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 243872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 243972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 244072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 244172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 244272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 244372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 244472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 244572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 24465d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 24475d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 2448ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("meta: %s @ %lld", chunk, (long long)offset); 24492d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer switch ((int32_t)mPath[4]) { 245072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 245172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 245272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 245372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 245472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 245572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 245672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 245772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 245872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 245972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 246066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 246166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 246266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 246366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 246466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 246572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 246672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 246772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 246872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 246972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 247072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 247172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 247272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 247372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 247472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 247572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 247672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 247772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 247872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 247972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 248072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 248172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 248272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 248372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 248472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 248572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 248672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 248772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 248872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 248972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 249026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 249126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 249226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 249326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 249426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 249511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 249611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 249711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 249811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 249911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 250011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 250111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 250211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 250311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 250411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 250511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 250672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 250772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 250872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 250972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2510afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2511afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2512afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 251372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 251472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 251572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 251672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 251772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 251826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 251926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2520afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 252126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2522afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2523afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2524afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 252526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 252626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 252726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 252826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 252926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 25305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 25315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 25325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 25335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 25345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 25355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 25365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 25375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 25385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 25395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 25405d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 25415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 25425d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 25435d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 25448c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 25458c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 25468c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 25478c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 25488c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 25498c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 25508c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 25518c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 25528c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 25538c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 25548c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 25558c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 25568c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 25578c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 25588c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 2559f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2560f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2561f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 25628c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 25638c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 25648c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 25655d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 25668c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 25675d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 25685d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 25695d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 25705d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 25715d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 25725d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 257326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 257472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 257572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 257672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 257772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2578328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 257972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 258072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 258172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 258272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 258372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 258472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 258526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 258626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 258726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 258826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 258926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 259026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 259126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 259226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 259326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 259472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 259526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 259672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 259772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 259826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 259926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 260026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 260126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 260226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 260326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 260472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 260572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 260672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 260772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 260872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 260972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 261072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 261172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 261272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 261372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 261472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 261572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 261672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 261772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 261872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2619fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 26205cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake if (size < 4 || size == SIZE_MAX) { 2621fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2622fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2623fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 26245cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 26258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 26268da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 26278da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 2628fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2629fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2630fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2631fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2632fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2633fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2634fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2635fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2636fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2637fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2638fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2639fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2640fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2641fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2642fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2643fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2644fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2645fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2646fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2647fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2648fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2649fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2650fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2651fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2652fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2653fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2654fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2655fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2656fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2657fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2658fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2659fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2660fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2661fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2662fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2663fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2664fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2665fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2666fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2667fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2668fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2669fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2670fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2671fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2672fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2673fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2674fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2675fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2676fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2677fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2678fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2679fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2680fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2681fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2682fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2683fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2684fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2685fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2686fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2687fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2688fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2689fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2690fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2691fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2692fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 26939458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake if (size < 6) { 26949458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake return ERROR_MALFORMED; 26959458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake } 26969458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake 2697fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2698fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2699fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2700fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2701fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2702fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2703fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2704fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2705fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2706fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2707fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2708fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2709fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2710fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2711fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2712fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2713fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2714fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2715fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2716fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2717fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2718fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2719fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 27205cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake buffer[size] = 0; 2721fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2722fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2723fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2724fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2725fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2726fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2727fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2728fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2729fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2730fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2731fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2732fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2733fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2734fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2735328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2736328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2737328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2738328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2739328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2740328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2741328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2742328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2743328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2744328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2745328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2746328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2747328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2748328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2749328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2750328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2751328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2752328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2753328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2754328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2755328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2756328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2757328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2758328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2759328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2760328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2761328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2762328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2763328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2764328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2765328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2766328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2767328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2768328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2769328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2770328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2771328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2772328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2773328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2774328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2775328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2776328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2777328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2778328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2779328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2780328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2781328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2782328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2783328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2784328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2785328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2786328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2787328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2788328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2789328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2790328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2791693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 279220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 279320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2794693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 279520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 279620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 279720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 279820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 279920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2800693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 280120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 280220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 280320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 280420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 280520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 280620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2807371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 2808371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 2809371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 2810371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2811c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2812c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 2813c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 2814c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 2815c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 2816c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *t = &mTrex.editItemAt(index); 2817c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 2818c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 2819c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2820c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2821c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2822c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2823c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2824a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 2825ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2826942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen return new MPEG4Source(this, 282705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 2828c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 282920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 283020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2831bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 2832bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 2833bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 2834bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2835bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2836bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 2837bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 2838bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 2839bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2840bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2841bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 2842bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2843bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 28443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 28453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 28463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 28473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 28483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 2849bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2850bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2851bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2852bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 2853bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2854bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2855bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2856bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2857ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 2858169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 2859ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 2860169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 2861169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 2862169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 28632e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (track->timescale == 0) { 28642e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale invalid."); 28652e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 28662e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 28672e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 2868bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 2869bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 2870bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2871f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 2872f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 2873f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 2874f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 2875f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 2876f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 2877f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 2878f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 2879f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 2880f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 2881f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 2882f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 2883f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 2884f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 2885f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 2886f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 2887f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 2888f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 2889f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 2890f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 2891f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 2892f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 2893f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 2894f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 2895f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 2896f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 2897f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 2898f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 2899f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 2900f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 2901f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 2902f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 2903f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 2904f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2905f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 2906f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2907f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 2908f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 2909f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 2910f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 2911f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 2912f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 2913f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 2914f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 2915f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2916f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 2917f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 2918f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 2919f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2920f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 2921f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 2922f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2923ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 2924ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 2925ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 292681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 292781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 292881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 292981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 293081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 293181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 293281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 293381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 2934f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2935f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2936f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 293781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 293881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 293981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 294081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 2941633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 2942633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 2943633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 2944633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 294529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 2946633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 2947633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 2948633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 2949ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 2950ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 2951ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 2952ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 2953ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2954ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2955ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2956b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 2957ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar printf("ESD of size %zu\n", csd_size); 2958b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(csd, csd_size); 2959b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 2960ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2961a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 2962a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 2963a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 2964a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 2965a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2966a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 2967a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 2968a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2969ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 2970ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2971ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2972ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 297300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 297400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 297500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 297600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 297700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 2978aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 2979aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 2980ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2981aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 2982aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 2983ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2984ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2985f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2986f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2987f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2988db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 2989db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 2990db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 2991aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 2992aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 2993ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 2994ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 2995ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 2996ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 2997ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2998ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2999aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 3000aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 3001ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 3002595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 300300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 300400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 300500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 3006ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3007ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 300800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 300900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 3010595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 3011f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 301200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 3013b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t extSampleRate __unused; 301400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 301500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 3016595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 3017595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 301800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 301900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 302000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 302100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 302200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 302300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 3024595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 302500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 302600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 3027ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3028ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3029f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 3030f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 3031f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 3032f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 3033f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 3034f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 3035f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 3036f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 3037f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 3038f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 3039f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3040f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 3041f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 3042f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3043f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 3044f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 3045f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 3046f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 3047f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3048f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 3049f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 3050f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3051f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3052f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 3053f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 3054f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 3055f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3056f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 3057f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 3058f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3059f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3060f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 3061f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 3062f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 3063b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t frameLengthFlag __unused = br.getBits(1); 3064f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3065f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 3066f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3067f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 3068b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t coreCoderDelay __unused = br.getBits(14); 3069f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3070f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 307145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 307245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 307345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 307445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 307545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 307645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 307745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 307845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 307945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 308045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 308145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 308245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 308345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 308445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 308545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 308645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 308745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih TRESPASS(); 308845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 308945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 309045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 309145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 309245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 3093f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 309445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 3095f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 3096f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 3097b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t ElementInstanceTag __unused = br.getBits(4); 3098b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t Profile __unused = br.getBits(2); 3099b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SamplingFrequencyIndex __unused = br.getBits(4); 3100f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 3101f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 3102f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 3103f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 3104b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumAssocDataElements __unused = br.getBits(3); 3105b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumValidCcElements __unused = br.getBits(4); 3106f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3107f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 3108f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 3109b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MonoMixdownElementNumber __unused = br.getBits(4); 3110f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3111f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3112f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 3113f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 3114b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t StereoMixdownElementNumber __unused = br.getBits(4); 3115f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3116f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3117f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 3118f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 3119b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MatrixMixdownIndex __unused = br.getBits(2); 3120b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t PseudoSurroundEnable __unused = br.getBits(1); 3121f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3122f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3123f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 3124f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 3125f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 3126b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t FrontElementTagSelect __unused = br.getBits(4); 3127f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 3128f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3129f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3130f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 3131f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 3132b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SideElementTagSelect __unused = br.getBits(4); 3133f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 3134f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3135f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3136f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 3137f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 3138b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t BackElementTagSelect __unused = br.getBits(4); 3139f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 3140f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3141f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 3142f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3143f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 3144b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t LfeElementTagSelect __unused = br.getBits(4); 3145f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 3146f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3147f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 3148f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 3149f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 3150f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3151f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3152f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3153f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3154ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 3155ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 3156ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3157ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3158f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3159f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3160f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3161ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 3162ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 3163ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3164ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 31653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 3166ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 3167ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3168ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3169ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 3170ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3171ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 3172ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 3173ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3174ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 31753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 3176ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 3177ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3178ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3179ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 3180ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3181ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 3182ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 3183ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 318420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 318520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 318620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 3187942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 318820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 3189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 319048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 319105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 319205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 3193c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 319405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 3195942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 3196942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 319720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 319848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 319920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 320020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 320105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 320205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 3203c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 320405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 320505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 320605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 3207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 3208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 3209ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 3210ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 321120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 32123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 32136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 321420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 321520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 321620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 3217dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 32180024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 3219ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3220c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 3221c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3222ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 322348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 3224ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 3225ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 3226ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 3227ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 3228ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 3229ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 3230ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 3231ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 3232ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3233ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 323420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 323520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 3236dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 323720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 323818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 32393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 32406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 32416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 32426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 32436064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 32446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 32456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 32466064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 32476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 32486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 32496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3250ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 32516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 32526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 32536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 32543b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 32553b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 32563b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 32573b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 32583b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 32593b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 32603b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 32613b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 32623b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 7); 32633b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 32643b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 32653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 32666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 326705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 326805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 326905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 327005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 327105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 327205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 327305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 327420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 327520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 327620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 327720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 327820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 327920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3280ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3281ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 328220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 328320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 328420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 32857b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 32867b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3287dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 328820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 328920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3290dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 329120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3292dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 329320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3294dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 329520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 329620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 329720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 329820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3299738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 3300738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 330120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3302738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 33030024245e134467d120b40099da16c467dc365e76Andreas Huber 33048da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 33058da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 33068da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 33078da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 33088da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 330920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 331020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 331120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 331220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 331320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 331420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 331520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 33167b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 33177b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3318dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 331920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 332020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 332120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 332220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 332320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 332420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33250024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 33260024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 33270024245e134467d120b40099da16c467dc365e76Andreas Huber 332820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 332920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 333020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 333120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 333220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 333320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 333420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 333520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 333620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 333705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 333805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 333905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 334005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 334105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 334205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 334305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 334405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 334505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 334605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 334705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 334805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 334905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 335005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 335105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 335205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 335305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 335405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 335505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 335605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 335705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 335805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 335905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 336005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 336105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 336205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 336305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 3364ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset); 336505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 336605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 336705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 336805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 336905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 337005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 337105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 337205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 337305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 337405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 337505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 337605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 337705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 337805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 337905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 338005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 33813f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 33823f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 33833f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 33843f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 33853f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 33863f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 33873f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 33883f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 33893f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 33903f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 33913f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 33923f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 33933f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 33943f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 339505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 339705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 339905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 340005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 340105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 340205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 340305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 340405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 340505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 340605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 340705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 340805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 340905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 341005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 341105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 341205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 341305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 341605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 341705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 341805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3420ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3421ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3422ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3423ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3424ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3425ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3426ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3427ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3428ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3429ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3430ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3431ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3432ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3433ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3434ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3435ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3436ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3437ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 3438ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 3439ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 3440ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 3441ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3442ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3443ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3444ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 344505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 344605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 344705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 344805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 344905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 345005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 345105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 345205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 345484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3455ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3456ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3457ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3458ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3459ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3460ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3461ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3462ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3463ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3464ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3465ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3466ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3467ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3468ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3469ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3470ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3471ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3472ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3473ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3474ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3475ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3476ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3477ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3478ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3479ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3480ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3481ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3482ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3483ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3484ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3485ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3486ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3487ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3488ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3489ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3490ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3491ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3492ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3493ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3494ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3495ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3496ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3497ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3498ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3499ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 350048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3501ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3502ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 350348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 350448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 350548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 350648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3507ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3508ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3509ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3510ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3511ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3512ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3513ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3514ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3515ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 351684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 351784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3518ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3519ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3520ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3521ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3522ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3523ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3524ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3525ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3526ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3527ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3528ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3531ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3532ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3533ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3535ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3536ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3537ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3538ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3540ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3541ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3542ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3543ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3544ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3545ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3546ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3547ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3548ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3549ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3550ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3551ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3552ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3553ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3554ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3555ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3556ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3557ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3558ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3559ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3560ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3561ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3562ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3563ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3564ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3565ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3566ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3567ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3568ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 356948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 357048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3571ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3572ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3573ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3574ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3575ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3576ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3577ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3578ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3579ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3580ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 358148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 358248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 358348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3584ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 358548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 358648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 358748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3588ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3589ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3590ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 359148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 359248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 359348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 359448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 359548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 359648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 359748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 359848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 359948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 360048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 360148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 360248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 360348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3604ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 360548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 360648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 360748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3608ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3609ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3610ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3611ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3612ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3613ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3614ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3622ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 363105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 363605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 363705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 363805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 364005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 364105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 364205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 364305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 364505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 364705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 364805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 364905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 365105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 365205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 365305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 365505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 365605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 365805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 365905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 366005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 366105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 366305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 366405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 366505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 367105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 367205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 367305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 367605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 367905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 368305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 368405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 368505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 368805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 368905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 369105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 369205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 369405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 369505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 369605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 369705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 369905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 370005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 370105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 370205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 370305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 370405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 370505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 370705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 370805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 370905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 371005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 371105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 371205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 371305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 371405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 371505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 371605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 371705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 371805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 371905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 372005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 372105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 372205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 372305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 372405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 372505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 372605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 372705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 372805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 372905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 373005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 373105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 373205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 373305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 373405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 373505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 373605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 373705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 373805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 373905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 374005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 374105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 374205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 374305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 374405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 374505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 374605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 374705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 374805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 374905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 375005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 375105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 375205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 375305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 375405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 375505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 375605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 375705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 375805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 375905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 376005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 376105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 376205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 376305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 376405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 376505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 376605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 376705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 376805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 376905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 377005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 377105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 377205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 377305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 377405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 377505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 377605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 377705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 377805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 377905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 378005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 378105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 378205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 378305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 378405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 378505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 378605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 378705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 378805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 378905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 379005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 379105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 379205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 3793c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 3794c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 379505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 379605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 379705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 379805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 379905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 380005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 380105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 380205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 380305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 380405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 380505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 380605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 380705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 380805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 380905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 381005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 381105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 381205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 381305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 381405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 381505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 381605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 381705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 381805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 381905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 382005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3821ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar if (size < (off64_t)(sampleCount * bytesPerSample)) { 382205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 382305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 382405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 382505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 382605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 382705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 382805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 382905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 383005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 383105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 383205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 383305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 383405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 383505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 383605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 383705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 383805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 383905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 384105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 384205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 384305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 384405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 384605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 384805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 384905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 385005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 385105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 385205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 385305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 385405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3855a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 3856ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 385705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 385805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 385905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 386005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 386105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 386205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 3863c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 386405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 386505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 386605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 386705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 386805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 386905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 387005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 387205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 387305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 38757b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 38767b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 387720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 387820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 387920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 38816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 38826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 38836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 38846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 38856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 38866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 38876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 38886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 38896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 38906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 38916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 38926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 38936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 38946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 38956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 38966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 38976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 38986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 389920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 390020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 39017b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 39027b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 390420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 390605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 391020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3911abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 3912abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 391320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 3914abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 3915abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3916abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 3917abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 3918abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 3919abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3920abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3921abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 3922abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 3923abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3924abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 3925abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 3926abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 3927abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3928abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 3929abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 3930abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3931abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3932abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 393320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 3934abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 3935599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 3936abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 3937abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3938abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3939abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 3940abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 3941abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 3942abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3943abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3944abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3945abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 3946abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 3947abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 3948abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 3949abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 395020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3951788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 3952788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 3953788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 3954788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 3955788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 3956788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 395720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 39585295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 39595295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 39605295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 39615295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 39625295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 39635295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 39645295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 39655295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 396720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 396820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 396920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3970abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3971abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 3972abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3973abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3974abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 3975abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 3976abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 3977abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 3978abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3979df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 3980abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 3981abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 3982abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 3983abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 3984abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 3985abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3986abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 398720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 398820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 398920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 399020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 399120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 399220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 399320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 399420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3995c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 39960024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 3997170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 39988bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 3999dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 4000dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 4001dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 400220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4003c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 4004c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 4005170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 400620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4007dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4008dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4009dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4010dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4011dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 4012c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 4013dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4014ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 4015dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4016dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 40170024245e134467d120b40099da16c467dc365e76Andreas Huber } 401820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 4020dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 4021dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 402234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 4023dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4024dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 4025dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4026dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4027dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4028dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 4029dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4030dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 40317b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4032dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 4033dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 403448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 40354678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4036170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4037170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4038abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4039abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4040abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4041abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4042abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4043abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 40448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 40458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 40468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 40478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4048dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 4049dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4050dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 40513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 4052dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 4053dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4054dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4055dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4056dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4057dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4058dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 4059dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 4060dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 40616064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 4062dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4063dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 4064dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 4065dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 40666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 4067e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 406829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 4069e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4070e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 4071e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 4072e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4073e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 4074e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 4075dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4076dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 40777b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 40786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 4079dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 40807b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4081dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 40826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 40836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 4084dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4085dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 4086dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4087dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4088dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4089dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4090dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 4091dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4092dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4093dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 4094dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 4095dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 4096dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 4097dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 4098dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4099dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4100dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 4101dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 4102dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4103dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 4104dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 410520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 410620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 410720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 410820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 410920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4110dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 411120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 411220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4113dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4114dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4115dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 41166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 4117dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4118dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 4119dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 4120dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 4121e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 412334fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 412434fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 412534fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 412634fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 412734fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 412834fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 412934fe252c89e33572d01fea981b58d7b115e76164James Dong } 4130e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 413134fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 413229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 4133dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 4134dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 4135dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 4136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4137dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 4138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 4139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 4140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4141dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4142dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 4143dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4144dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4145dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 4148dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 4149dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 4150dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 4151dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4152dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 4153dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4154dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 4155dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4156dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 415720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 415848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 41594678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4160170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4161170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4162abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4163abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4164abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4165abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4166abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4167abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 41688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 41698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 41708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 41718bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 417220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 417320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 417420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 417520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 417620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 417720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 417820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 417920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 418020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 418105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 418205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 418305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 418505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 418705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 418805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 418905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 419105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 419305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 419405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 419505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 419705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 419805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 419905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 420005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 420105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 420205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 420305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 42043f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 420505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 420605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 420705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 420805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 420905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 421005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 421105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 421205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 421305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 421405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 421505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 421605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4217ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 4218ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4219ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4220ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 4221ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 4222ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 4223ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 4224ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 4225ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4226ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4227ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 4228ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 4229ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 423005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 423105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 423205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 423305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 423405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 423505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 423605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 423705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 423805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 423905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 424005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4241442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 424205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 424305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 424405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 424505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 424605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 424705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 424805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 42493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 42503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 42513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 42523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4253ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 425405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 425505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 425605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 425705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 4258ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4259ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4260ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 426105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 426205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 426305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 426405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 426505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4266c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 426705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 426805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 426905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 427105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 427305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 427405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 427505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 427605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 427705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 427805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 428048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 428148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 428248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 428348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 428448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 428548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 428648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 428748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 428848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 428948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 429048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 429148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 429248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 429348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 42943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 429505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 429605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 429705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 429805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 429905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 430005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 430105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 430205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 430305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 430405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 430505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 430605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 430705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 430805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 430905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 431005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4311170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4312170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 431305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 431405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 431505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 431605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 431705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 431805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 431905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 432005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 432105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 432205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 432305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 432405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 432505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 43263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 432705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 432805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 432905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 433005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 433105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 433205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 433305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 433405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 433505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 433605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 433705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 433805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 433905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 434005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 434105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 434205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() < mNALLengthSize + nal_size) { 434305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 434405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 434505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 434605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 434705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 434805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 434905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 435005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 435105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 435205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 435305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 435405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 435505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 435605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 435705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 435805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 435905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 436005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 436105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 436205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 436305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 436405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 436505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 436605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 436705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 436805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 436905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 437005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 437105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 437205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 437305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 437405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 437505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 437605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = 437705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 437805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 437905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 438005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 438105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 438205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 438305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 438405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 438505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 438605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 438705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 438805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 438905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 439105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 439205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 439305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 439505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 439605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 439705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 439805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 440005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isMalFormed = (srcOffset + mNALLengthSize > size); 440105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 440205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 440305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 440405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 440505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isMalFormed = srcOffset + nalLength > size; 440605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 440705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 440805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 440905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("Video is malformed"); 441005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 441105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 441205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 441305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 441405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 441505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 441605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 441705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 441805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 441905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(dstOffset + 4 <= mBuffer->size()); 442005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 442105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 442205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 442305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 442405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 442505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 442605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 442705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 442805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 442905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 443005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 443105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 443205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 443305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 443405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 443505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4436170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4437170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 443805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 443905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 444005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 444105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 444205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 444405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 444505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 444605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 444805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 444905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 445005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 445105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 445205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 445305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 445405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 445505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 445605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4457bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4458bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 4459bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4460bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 4461bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4462bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4463bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4464bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4465bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4466bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4467bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4468bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4469bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4470bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 44711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 447320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 447420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 447534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 447620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 447720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 447820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 447920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 448020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4481b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4482b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 44830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4484ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4485983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 448618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 44875a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 448820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 448920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 449020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 449120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 449220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 449320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 449420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 44961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 44971b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 44981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 44991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 45003b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 45013b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 45021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 45031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 45041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 45054cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 45064cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 45074cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 45084cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 45094cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 451058fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 451158fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 451258fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 45131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 45141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 45151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 45161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 45171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 45181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 45191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 45201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 45211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 45221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 45231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 45241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 45251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 45261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 45271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4528a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4529a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4530a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 45311b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4532a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4533a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4534a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4535a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 45361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4537a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4538a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4539a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4540a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 45411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4542a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4543a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4544a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4545a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4546a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4547a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4548a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4549a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4550a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4551a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4552a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4553a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 45541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 45551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 45561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4557a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4558a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4559a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4560a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4561a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4562a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4563a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4564a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4565a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4566a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4567a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4568a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4569a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 4570a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 457105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 457205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 4573ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset); 4574a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4575a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4576a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4577a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4578a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4579a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4580a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4581a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4582a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4583a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4584a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4585a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4586a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4587a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4588a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4589a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4590a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4591a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4592a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4593a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4594a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4595a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4596a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4597a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4598a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4599a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4600a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4601a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4602a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4603a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4604a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4605a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4606a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 46071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 46081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4609a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4610a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4611a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4612a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4613a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4614a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4615a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4616a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4617a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4618a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4619a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 46201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4621a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4622a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 46231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 46241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4625a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 46261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 46271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 46281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 46291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 46305a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 46311b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4632a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4633a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4634a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4635a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4636ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset); 4637a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4638a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 46391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 46401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 46411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 46421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 46435a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4644a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4645a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 46461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 46471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 46481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 46491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 46505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 46511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 46521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 46531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 46541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 46551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 46561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 465720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 4658