MPEG4Extractor.cpp revision 0517e0b6e4a86f34388631416dd6b3b4fcb91ff8
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" 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2166326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include "include/ESDS.h" 2489e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ABitReader.h> 31d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson#include <media/stagefright/foundation/ABuffer.h> 32ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 33a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h> 42328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h" 43fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 50693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 5148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 5205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 5305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 5405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 6205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 65693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 66693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 697b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 71693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 73693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 7605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 7705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 7805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 7905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 8005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 8105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 8205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 85ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 86ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 87ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 88ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 8948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 90ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 91ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 92ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 93ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 94ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 95ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 96ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1080024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1090024245e134467d120b40099da16c467dc365e76Andreas Huber 1106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 11105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 11205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 11305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 11605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 11705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 11805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 11905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 12005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 12105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 12205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 12305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 12405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 12505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 12605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 12705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 12805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 12905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 13305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 13405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 164c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 165c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 168c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 177c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 212c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 224c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 232c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 263377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 30118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 30418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 306371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 30718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 308371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 31018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 313e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 314e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 31518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 31818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 321dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 32748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 32848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 32948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 33048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 33148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 33248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 33348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 33448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 33548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 33648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 33748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 33848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 33948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 34048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 341693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 34205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen : mSidxDuration(0), 34305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mMoofOffset(0), 34405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 345bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3467be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 347fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 34972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 350dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 351dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 352dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 364dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 365dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 366dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 367dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 368dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf->IPMPData; 369dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 370dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 371dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 372dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 373ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 374ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 375ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 376ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 38005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 38105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 38205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 38305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 38405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 3867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 3877be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 38872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 3897be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 3907be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 39172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 3927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 3937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 397ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 408ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: %d tracks", n); 409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4137e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 429371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 430371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 431371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 432371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 44005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 44105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 44205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 44305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 44405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 44505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 44605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 44705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 44805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 44905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 45005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 45105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 45205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 45305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 45405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 45505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 45605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 45705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 46648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 46748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 46848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 46948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 47048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 47148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 47248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 474bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 475bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 478c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 48005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (true) { 48105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 48205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err == OK) { 48305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 48405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 48505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 48605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 48705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(offset, hdr, 8) < 8) { 48805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 48905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 49005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 4913f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 49205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // store the offset of the first segment 49305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mMoofOffset = offset; 4943f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } else if (chunk_type != FOURCC('m', 'd', 'a', 't')) { 4953f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // keep parsing until we get to the data 4963f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen continue; 49705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 49805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 501bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 50272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 503bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 504bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 50572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 50672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 50772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 50872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 5094678a6dc5f09008481524949a9667af5a6190374Andreas Huber mInitCheck = OK; 510bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 511bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 514bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 515ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 516ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 517ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int psshsize = 0; 518ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 519ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 520ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 521ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (psshsize) { 522ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 523ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 524ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 525ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 526ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 527ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 528ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 531ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 532bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 535dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 536dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 537dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 538dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 539dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 540dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 541dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 542dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 543dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 544dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 545dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 558dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 559dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 560dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 561dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 562dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 563dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 564dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 565dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 566dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 567dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 568dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 569dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 570dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 571dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 572dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 573dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 57484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 57584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t classSize = size; 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang classSize = size; 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPData = new char[sinf->len]; 687f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 689f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 70572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 70672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 70772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 70872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 70972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 71072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 71172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 71272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 71372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 71472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 71572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 71672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 71772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 71872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 71972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 72072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 72172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 72372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 72472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 72572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 72672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 72772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 72872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 72972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 73172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 73272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 73372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 73572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 73672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 73872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 73972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 740c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 7415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("entering parseChunk %lld/%d", *offset, depth); 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 74334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 748c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 75134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 75671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 75771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 75871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 75971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 76071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 76171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 76271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 76371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 76805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth); 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 776ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 777ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 778ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 779ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 780ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 781ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 782ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 784ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 785ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 78972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 790c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 793515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 79472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 795c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 79672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 79772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 79872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 79972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 80072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 80172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 80272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 803bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 804bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 805bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 806bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 80772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 80872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 80972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 81072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 82272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 82372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 824ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 825ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 8260a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 82850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 8293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 83050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 831b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 832b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 833b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 83450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 83550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 83650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 83750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 83850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 83950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 84050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 8411edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 8421edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 84350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 84450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 8456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 846bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 8476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 8486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 849bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 850bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 851bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 852bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 853bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 854bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 855bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 856bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 857bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 858bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 859bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 8606f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 861bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 862bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 863bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 864bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 865c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 874bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 875bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 876bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 877bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 8786f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 8796f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 8806f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 8816f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 8826f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 8836f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 8846f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 8856f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 8866f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 8876f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 8886f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 8896f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 8906f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 8916f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 8926f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 8936f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 8946f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 8956f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 8966f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 897bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 898bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 899bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 900bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 901bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 902bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 903bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 905dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 906dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 907dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 908dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 909dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9140a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 9150a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 9160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 9170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 9180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 9190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 9200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 9210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 9250a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 9260a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9270a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9280a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9290a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 9300a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 9310a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 932fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 933210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 9340a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9350a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 9360a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 9370a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 9380a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9390a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 9400a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 9410a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 9420a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9430a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9440a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 9450a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 9460a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 9470a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 9480a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 9490a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9500a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9510a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 9520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 9530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9550a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9560a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 957fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 958fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 959fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 9600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 9620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 9630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 9640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 9650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 9670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 9680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingus = duration - (segment_duration + media_time); 970465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 971465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 972465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 973465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 974465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 975465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 9760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 9770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 9780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 9810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 983ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 984ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 9850517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 9860517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 98748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 989ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 990ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 991ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 992ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 993ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 99448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 99548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 99648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 99748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 99848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 99948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1000ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1001ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1002ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1003ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1004ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10050517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10060517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1007ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1008ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1009ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1010ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1011ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1012ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1013ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1014ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1015ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1016ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1017ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1018ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1019ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1020ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1021ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1022ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1023ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1027ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1028ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1036ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1037ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1038ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1039ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1050ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1051ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1052ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1053ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 10560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10570517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1058ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1059ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1060ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10680517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10690517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1071ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1072ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1074ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (pssh.datalen + 20 > chunk_size) { 1083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.data = new uint8_t[pssh.datalen]; 1088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 109820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11000517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11010517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 110734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1113c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 111620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 112434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 113320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 113434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 113520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 113620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 113720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 113820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 114020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 114105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 114234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 114320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 114520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 114620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // ffmpeg sets duration to -1, which is incorrect. 114805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 114905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 115005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 115120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 115348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 115420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 11567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 11577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 11587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 11597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 11607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 11617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 11627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 11637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 11647a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 11657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 11667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 11677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 11687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 11697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 11707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 11717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 11727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 11737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 11747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 11757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 11767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 11777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 11787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 11797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 11807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 11817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 118320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 118720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1192c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1193bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1194bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1195bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 119634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 119720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 120220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 120320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 120720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 12093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 12103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 12113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1212ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 12133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 12143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1215ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1216ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 12173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 12183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 12193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 12203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 12213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 122220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1223c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 122920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1231bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1232bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1233bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1234bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 123948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1241371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 124620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 124720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 125020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 125548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 125881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 125981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 126048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 126148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 126248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 126348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 126681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1270c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 127320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1278bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1279bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1280bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1281bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 128320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1286ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1288e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1289e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 129120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 12927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 12937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 130120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1309ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1310a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1311a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1312a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1313a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1314a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1315a6256238d9015c42129fe43791968768fe501efaJames Dong 1316134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1317134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 131820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1319ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1320ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1321ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1322ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1326c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 132820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 132920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 133020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 133120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 133320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1334bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1335bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1336bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1337bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 133820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 133920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 134220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 134420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 13490517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13630517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 13640517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 137320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 137420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 137520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 137720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 137820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13790517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 13800517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 138220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1385738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 138649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 138749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 138849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 138949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 139049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1391738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 139205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 139305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 139405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 139505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 139605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 139705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 139805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 139905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 140005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t width, height; 1401f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || 1402f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar !mLastTrack->meta->findInt32(kKeyHeight, &height)) { 140305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1404f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1405f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 140605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1407f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 14084256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 14094256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1410f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1411f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // AVC requires compression ratio of at least 2, and uses 1412f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1413f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1414f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1415f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1416f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1417f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 141805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1419f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 142005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1421113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 14224256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 14234256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1424113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1425113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1426113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1427113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1428113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1429113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1430113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1431113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1432113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1433113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1434113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1435113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1436113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1437113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1438113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 14440517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14450517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 144620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 144720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 144820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 145020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 145120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 145220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 145520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 14584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 14590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 14614931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 14624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 14634931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 14644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 14654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 14664931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 14674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 14684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 14694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 14704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 14714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 147220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 147320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 14740517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14750517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 148120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 148220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 148320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 148420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 148520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 148620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14874948818cb91176df74c972ac27b2f392b5d148bcJames Dong // @xyz 14884948818cb91176df74c972ac27b2f392b5d148bcJames Dong case FOURCC('\xA9', 'x', 'y', 'z'): 14894948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 14900517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14910517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 14924948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Best case the total data length inside "@xyz" box 14934948818cb91176df74c972ac27b2f392b5d148bcJames Dong // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 14944948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 14954948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 14964948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 14974948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 14984948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 14994948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15004948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15014948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 15024948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 15034948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 15044948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 15054948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15064948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 15074948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 15084948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 15094948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 15104948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 15114948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15124948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15134948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 15144948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 15154948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 15164948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15174948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15184948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 15194948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 15204948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 15214948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15224948818cb91176df74c972ac27b2f392b5d148bcJames Dong 152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 15250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1532c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 153720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 153820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 153920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 154020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 154120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 154220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 154320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 154420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 154520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 154620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 154720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1549ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1550ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1551ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1552ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1553ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1554ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1555ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1556ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1557ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1558ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1559ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1560ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1561ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1562ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1563ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 156720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 156820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 15690517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15700517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1571d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 157220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 157334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1574d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 157520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 157620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 157720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 157820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1579d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 158020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1584244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1585244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 15860517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 158717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 158817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 158917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 159017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 159117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 159217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 159317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 159417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 159517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 159617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 159717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 159817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 159917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 160017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 160129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1602244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1603244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1604244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1605244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1606244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1607244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1608244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1609244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1610244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1611244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1612244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1613244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1614244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 161572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 161672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 161772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1618c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 16190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 1620bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1621bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1622bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 162372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 162472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 16250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 162672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 162772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 162872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 162972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 163072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1631ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1632ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1633ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1634ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1635ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1636ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1637ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 163872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 163972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1640c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 164172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 164272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 164372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 164472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 164572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 164672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 164772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1648bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1649bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1650bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1651bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 165272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 165372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 165472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 16555d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 16565d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 165772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 165872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 16590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 166172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1662fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 166372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 166472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 166572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 166672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 166772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 166872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 166972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 167072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 167172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 167272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 167372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 16740517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16750517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1676fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen if (chunk_data_size < 24) { 167772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 167872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 167972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1680fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint8_t header[24]; 168172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 168272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 168372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 168472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 168572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 168672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1687fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 168872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 168972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1690fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1691bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1692bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 169372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 169472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1695fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 169672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 169772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 169872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 169972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 170072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 170172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 170272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 170372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 170472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 170572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1708ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 1709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 17213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 17223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 17230517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17240517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 17253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 17263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 17273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 17283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 17293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 17323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1733e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1734e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1735e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 17363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 17373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 17403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 17437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 17443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 17453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 17463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 17473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 17483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 17493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 17503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint8_t *buffer = new uint8_t[size + chunk_size]; 17533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 17553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 17563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 17593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 17603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 17613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 17623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17630517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 17640517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 17663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 17693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 17703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 17727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 17737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 17747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 17757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 17767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 1777515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 1778515e855eae78aa495da58356486aaa666cb57fd1James Dong { 17790517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17800517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1781515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 17823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("chunk_data_size = %lld and data_offset = %lld", 1783515e855eae78aa495da58356486aaa666cb57fd1James Dong chunk_data_size, data_offset); 17841552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 1785515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 17861552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 1787515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 1788515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1789515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 1790515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 1791515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 17921552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1793515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1794515e855eae78aa495da58356486aaa666cb57fd1James Dong 1795515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 1796515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1797515e855eae78aa495da58356486aaa666cb57fd1James Dong 1798fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 1799fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 1800fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 1801fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 1802fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 1803fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 1804fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 18050517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18060517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1807fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 1808fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1809fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 1810fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 1811fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 1812fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1813fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 1814fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 1815fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1816328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 1817328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 18180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1820328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 1821328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 1822328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 1823328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 1824328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 1825328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 1826328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 1827328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 1828328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 18295d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 18305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 18315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 18325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 18335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 18345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 18355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 18365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 18375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 183805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 183905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 184005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 184105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 184205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 184305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 184405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 184520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 184620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 184720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 184820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 184920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 185020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 185120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 185220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 185320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 185420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 185505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 185605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 185705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 185805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 185905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 186005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 186105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 186205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 186305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 186405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 186505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 186605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 186705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 186805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 186905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 187005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 187105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 187205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 187305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 187405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 187505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 187605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 187705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 187805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 187905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 188005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 188105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 188205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 188305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 188405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 188505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 188605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 188705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 188805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 188905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 189005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 189105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 189205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 189305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 189405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 189505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 189605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 189705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 189805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 189905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 190005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 190105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 190205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 190305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 190405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 190505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 190605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 190705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 190805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 190905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 191005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 191105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 191205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 191305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 191405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 191505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 191605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 191705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset); 191805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 191905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 192005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 192105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 192205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 192305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 192405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 192505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 192605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 192705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 192805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 192905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 193005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 193105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 193205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 193305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 193405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 193505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 193605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 193705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 193805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 193905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 194005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 194105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 194205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 194305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 194405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 194505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 194605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 194705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 194805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 19493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 19503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 19513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 19523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 195305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 195405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 195505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 195605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 195705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 195805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 195905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 196005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 196105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 196205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 196305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxDuration = total_duration * 1000000 / timeScale; 196405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("duration: %lld", mSidxDuration); 196505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 196605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 196705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 196805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt64(kKeyDuration, mSidxDuration); 196905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 197005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 197105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 197205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 197305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 197405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 1975ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1976c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 1977ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1978ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1979ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1980ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1981ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1982ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1983ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1984ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1985ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1986ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1987ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1988ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1989ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1990c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 1991ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1992ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1993ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1994ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1995ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1996ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1997ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1998ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1999ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 2000ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2001ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2002ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2003ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2004ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2005ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2006ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 200704022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2008ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2009ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2010ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2011ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 201204022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 201304022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2014ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2015ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2016ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2017ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2018ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2019ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2020ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2021ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2022ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2023ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2024ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2025ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2026ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2027df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2028ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2029df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2030ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2031ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2032ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2033ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2034ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2035ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2036ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2037ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2038ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2039ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2040ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2041ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2042ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2043ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2044ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2045ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 20465ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2047ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2048ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2049ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2050ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2051ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2052ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2053ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2054b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2055b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2056ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2057ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2058b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2059b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2060ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2061ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2062ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2063ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2064fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 206572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 206672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 206772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 206872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 206972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 207072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 207172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 207272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 207372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 207472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 207572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 207672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 207772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 207872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 207972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 208072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 20815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 20825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 20835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("meta: %s @ %lld", chunk, offset); 208472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 208572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 208672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 208772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 208872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 208972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 209072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 209172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 209272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 209372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 209472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 209566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 209666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 209766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 209866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 209966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 210072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 210172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 210272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 210372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 210472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 210572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 210672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 210772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 210872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 210972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 211072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 211172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 211272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 211372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 211472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 211572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 211672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 211772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 211872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 211972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 212072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 212172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 212272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 212372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 212472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 212526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 212626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 212726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 212826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 212926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 213011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 213111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 213211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 213311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 213411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 213511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 213611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 213711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 213811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 213911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 214011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 214172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 214272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 214372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 214472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2145afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2146afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2147afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 214872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 214972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 215072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 215172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 215272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 215326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 215426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2155afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 215626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2157afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2158afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2159afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 216026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 216126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 216226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 216326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 216426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 21655d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 21665d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 21675d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 21685d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 21695d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 21705d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 21715d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21725d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 21735d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 21745d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21755d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 21765d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 21775d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 21798c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 21808c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 21818c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 21828c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 21838c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 21848c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 21858c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 21868c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 21878c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 21888c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 21898c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 21908c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 21918c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 21928c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 21938c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 21948c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 21958c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 21968c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 21975d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 21988c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 21995d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 22005d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 22015d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 22025d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 22035d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 22045d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 220526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 220672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 220772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 220872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 220972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2210328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 221172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 221272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 221372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 221472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 221572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 221672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 221726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 221826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 221926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 222026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 222126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 222226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 222326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 222426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 222526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 222672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 222726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 222872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 222972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 223026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 223126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 223226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 223326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 223426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 223526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 223672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 223772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 223872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 223972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 224072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 224172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 224272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 224372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 224472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 224572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 224672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 224772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 224872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 224972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 225072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2251fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 2252fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size < 4) { 2253fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2254fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2255fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2256fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint8_t *buffer = new uint8_t[size]; 2257fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2258fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2259fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2260fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2261fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2262fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2263fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2264fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2265fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2266fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2267fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2268fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2269fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2270fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2271fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2272fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2273fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2274fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2275fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2276fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2277fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2278fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2279fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2280fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2281fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2282fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2283fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2284fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2285fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2286fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2287fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2288fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2289fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2290fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2291fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2292fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2293fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2294fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2295fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2296fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2297fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2298fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2299fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2300fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2301fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2302fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2303fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2304fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2305fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2306fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2307fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2308fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2309fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2310fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2311fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2312fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2313fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2314fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2315fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2316fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2317fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2318fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2319fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2320fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2321fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 2322fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2323fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2324fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2325fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2326fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2327fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2328fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2329fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2330fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2331fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2332fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2333fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2334fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2335fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2336fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2337fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2338fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2339fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2340fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2341fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2342fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2343fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2344fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 2345fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2346fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2347fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2348fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2349fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2350fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2351fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2352fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2353fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2354fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2355fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2356fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2357fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2358fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2359328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2360328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2361328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2362328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2363328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2364328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2365328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2366328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2367328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2368328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2369328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2370328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2371328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2372328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2373328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2374328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2375328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2376328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2377328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2378328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2379328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2380328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2381328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2382328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2383328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2384328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2385328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2386328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2387328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2388328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2389328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2390328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2391328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2392328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2393328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2394328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2395328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2396328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2397328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2398328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2399328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2400328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2401328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2402328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2403328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2404328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2405328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2406328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2407328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2408328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2409328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2410328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2411328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2412328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2413328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2414328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 241620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 241720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 241920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 242020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 242120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 242220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 242320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 242520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 242620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 242720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 242820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 242920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 243020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2431371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 2432371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 2433371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 2434371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2435ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("getTrack called, pssh: %d", mPssh.size()); 2436ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 243805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 243905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries, mMoofOffset); 244020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 244120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2442bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 2443bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 2444bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 2445bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2446bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2447bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 2448bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 2449bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 2450bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2451bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2452bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 2453bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2454bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2455bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2456bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2457bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2458bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 2459bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2460bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2461bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2462bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2463169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber if (!track->sampleTable->isValid()) { 2464169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 2465169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 2466169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 2467169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 2468bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 2469bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 2470bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2471f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 2472f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 2473f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 2474f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 2475f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 2476f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 2477f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 2478f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 2479f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 2480f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 2481f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 2482f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 2483f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 2484f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 2485f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 2486f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 2487f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 2488f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 2489f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 2490f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 2491f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 2492f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 2493f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 2494f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 2495f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 2496f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 2497f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 2498f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 2499f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 2500f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 2501f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 2502f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 2503f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 2504f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2505f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 2506f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2507f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 2508f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 2509f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 2510f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 2511f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 2512f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 2513f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 2514f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 2515f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2516f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 2517f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 2518f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 2519f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2520f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 2521f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 2522f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2523ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 2524ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 2525ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 252681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 252781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 252881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 252981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 253081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 253181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 253281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 253381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 253481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 253581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 253681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 253781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 2538633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 2539633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 2540633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 2541633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 254229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 2543633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 2544633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 2545633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 2546ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 2547ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 2548ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 2549ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 2550ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2551ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2552ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2553ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 2554ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 2555ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 2556ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 2557ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2558a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 2559a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 2560a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 2561a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 2562a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2563a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 2564a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 2565a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2566ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 2567ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2568ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2569ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 257000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 257100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 257200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 257300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 257400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 2575aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 2576aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 2577ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2578aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 2579aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 2580ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2581ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2582db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 2583db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 2584db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 2585aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 2586aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 2587ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 2588ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 2589ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 2590ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 2591ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2592ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2593aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 2594aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 2595ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 2596595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 259700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 259800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 259900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 2600ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2601ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 260200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 260300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 2604595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 2605f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 260600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 260700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent int32_t extSampleRate; 260800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 260900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 2610595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 2611595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 261200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 261300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 261400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 261500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 261600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 261700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 2618595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 261900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 262000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 2621ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2622ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2623f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 2624f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 2625f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 2626f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 2627f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 2628f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 2629f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 2630f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 2631f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 2632f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 2633f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2634f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 2635f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 2636f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2637f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 2638f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 2639f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 2640f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 2641f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 2642f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 2643f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 2644f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2645f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2646f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 2647f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 2648f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t extensionSamplingFrequency = br.getBits(4); 2649f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 2650f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2651f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 2652f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 2653f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2654f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2655f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 2656f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 2657f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 2658f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t frameLengthFlag = br.getBits(1); 2659f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2660f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 2661f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2662f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 2663f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t coreCoderDelay = br.getBits(14); 2664f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2665f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2666f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t extensionFlag = br.getBits(1); 2667f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2668f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (numChannels == 0 ) { 2669f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 2670f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 2671f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t ElementInstanceTag = br.getBits(4); 2672f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t Profile = br.getBits(2); 2673f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SamplingFrequencyIndex = br.getBits(4); 2674f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 2675f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 2676f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 2677f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 2678f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumAssocDataElements = br.getBits(3); 2679f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumValidCcElements = br.getBits(4); 2680f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2681f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 2682f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 2683f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownElementNumber = br.getBits(4); 2684f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2685f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2686f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 2687f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 2688f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownElementNumber = br.getBits(4); 2689f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2690f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2691f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 2692f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 2693f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndex = br.getBits(2); 2694f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t PseudoSurroundEnable = br.getBits(1); 2695f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2696f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2697f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 2698f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 2699f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 2700f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementTagSelect = br.getBits(4); 2701f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 2702f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2703f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2704f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 2705f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 2706f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementTagSelect = br.getBits(4); 2707f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 2708f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2709f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2710f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 2711f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 2712f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementTagSelect = br.getBits(4); 2713f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 2714f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2715f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 2716f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2717f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 2718f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t LfeElementTagSelect = br.getBits(4); 2719f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 2720f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2721f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 2722f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 2723f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 2724f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2725f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2726f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 2727f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 2728ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 2729ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 2730ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2731ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2732ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 2733ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 2734ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2735ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 27363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 2737ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 2738ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2739ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2740ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 2741ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2742ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 2743ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 2744ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2745ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 27463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 2747ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 2748ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2749ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2750ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 2751ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2752ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 2753ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 2754ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 275520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 275620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 275720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 275820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 2759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 276048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 276105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 276205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 276305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 276420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 276520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 276648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 276720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 276820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 276905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 277005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 277105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 277205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 277305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 2774ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 2775ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 2776ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 2777ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 277820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 27796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 278020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 278120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 278220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 2783dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 27840024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 2785ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2786ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 278748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 2788ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 2789ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 2790ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 2791ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 2792ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 2793ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 2794ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 2795ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 2796ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2797ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 279820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 279920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 2800dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 280120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 280218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 28036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 28046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 28056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 28066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 28076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 28086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 28096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 28106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 28116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 28126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 2813ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 28146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 28156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 28166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 28176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 281805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 281905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 282005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 282105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 282205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 282305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 282405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 282520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 282620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 282720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 282820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 282920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 283020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 2831ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 2832ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 283320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 283420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 283520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 28367b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 28377b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 2838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 283920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 284020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 2841dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 284220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 2843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 284420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 2845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 284620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 284720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 284820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 284920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2850738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 2851738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 285220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2853738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 28540024245e134467d120b40099da16c467dc365e76Andreas Huber 28550024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 285620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 285720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 285820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 285920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 286020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 286120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 286220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 28637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 28647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 2865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 286620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 286720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 286820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 286920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 287020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 287120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28720024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 28730024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 28740024245e134467d120b40099da16c467dc365e76Andreas Huber 287520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 287620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 287720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 287820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 287920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 288020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 288120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 288220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 288320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 288405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 288505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 288605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 288705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 288805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 288905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 289005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 289105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 289205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 289305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 289405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 289505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 289605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 289705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 289805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 289905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 290005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 290105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 290205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 290305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 290405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 290505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 290605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 290705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 290805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 290905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 291005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 291105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset); 291205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 291305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 291405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 291505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 291605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 291705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 291805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 291905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 292005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 292105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 292205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 292305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 292405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 292505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 292605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 292705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 29283f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 29293f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 29303f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 29313f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 29323f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 29333f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 29343f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 29353f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 29363f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 29373f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 29383f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 29393f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 29403f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 29413f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 294205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 294305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 294405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 294505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 294605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 294705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 294805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 294905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 295005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 295105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 295205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 295305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 295405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 295505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 295605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 295705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 295805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 295905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 296005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 296105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 296205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 296305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 296405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 296505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 296605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2967ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 2968ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 2969ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 2970ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 2971ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2972ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 2973ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 2974ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2975ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 2976ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 2977ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 2978ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 2979ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2980ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 2981ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 2982ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2983ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2984ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 2985ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 2986ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 2987ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 2988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 2989ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 2990ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2991ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 299205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 299305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 299405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 299505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 299605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 299705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 299805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 299905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 300084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 300184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3002ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3003ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3004ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3005ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3006ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3007ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3008ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3009ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3010ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3011ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3012ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3013ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3014ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3015ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3016ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3017ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3018ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3019ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3020ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3021ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3022ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3023ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3027ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3028ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3036ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3037ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3038ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3039ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 304748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 305048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 305148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 305248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 305348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3054ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 306384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 306484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3071ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3072ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3074ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 311648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 311748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3127ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 312848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 312948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 313048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 313248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 313348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 313448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 313848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 313948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 314048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 314148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 314248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 314348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 314448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 314548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 314648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 314748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 314848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 314948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 315048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 315248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 315348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 315448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3161ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 316205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 316305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 316405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 316505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 316605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 316705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 316805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 317005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 317105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 317205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 317305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 317405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 317505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 317605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 317705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 317805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 317905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 318005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 318105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 318205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 318305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 318405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 318505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 318605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 318705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 318805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 318905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 319005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 319105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 319205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 319305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 319405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 319505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 319605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 319705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 319805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 319905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 320005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 320105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 320205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 320305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 320405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 320505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 320605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 320705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 320805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 320905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 321005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 321105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 321205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 321305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 321405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 321505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 321605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 321705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 321805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 321905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 322005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 322105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 322205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 322305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 322405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 322505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 322605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 322705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 322805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 322905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 323005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 323105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 323205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 323305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 323405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 323505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 323605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 323705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 323805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 323905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 324005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 324105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 324205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 324305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 324405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 324505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 324605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 324705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 324805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 324905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 325005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 325105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 325205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 325305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 325405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 325505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 325605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 325705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 325805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 325905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 326005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 326105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 326205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 326305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 326405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 326505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 326605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 326705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 326805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 326905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 327005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 327105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 327205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 327305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 327405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 327505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 327605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 327705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 327805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 327905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 328005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 328105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 328205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 328305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 328405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 328505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 328605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 328705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 328805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 328905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 329005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 329105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 329205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 329305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 329405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 329505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 329605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 329705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 329805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 329905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 330005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 330105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 330205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 330305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 330405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 330505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 330605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 330705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 330805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 330905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 331005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 331105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 331205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 331305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 331405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 331505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 331605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 331705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 331805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 331905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 332005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 332105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 332205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 332305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 332405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 332505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 332605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 332705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 332805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 332905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 333005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 333105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 333205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 333305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 333405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 333505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 333605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 333705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 333805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 333905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 334005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 334105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 334205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 334305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 334405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 334505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 334605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 334705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 334805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 334905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 335005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 335105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 335205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 335305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 335405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 335505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 335605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 335705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 335805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 335905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 336005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 336105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 336205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 336305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 336405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 336505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 336605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 336705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 336805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < sampleCount * bytesPerSample) { 336905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 337005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 337105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 337205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 337305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 337405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 337505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 337605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 337705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 337805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 337905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 338005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 338105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 338205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 338305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 338405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 338505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 338605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 338705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 338805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 338905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 339005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 339105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 339305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 339505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 339605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 339705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 339805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 339905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 340005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 340105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3402ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("adding sample %d at offset 0x%08llx, size %u, duration %u, " 3403ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 340405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 340505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 340605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 340705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 340805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 340905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 341005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 341105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 341205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 341305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 341405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 341505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 341605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 341705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 341805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 341905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 342020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 34217b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 34227b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 342320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 342420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 342520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 34276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 34286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 34296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 34306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 34316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 34326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 34336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 34346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 34356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 34366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 34376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 34396064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 34406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 34416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 34436064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 34446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 344520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 344620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 34477b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 34487b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3449dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 345020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 345105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 345205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 345305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 345405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 345620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3457abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 3458abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 345920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 3460abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 3461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 3463abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 3464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 3465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3466abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3467abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 3468abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 3469abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3470abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 3471abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 3472abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 3473abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3474abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 3475abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 3476abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 347920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 3480abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 348120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 3482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 3483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 3486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 3487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 3488abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 3492abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 3493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 3494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 3495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 349620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3497788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 3498788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 3499788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 3500788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 3501788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 3502788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 350320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 35045295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 35055295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 35065295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 35075295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 35085295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 35095295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 35105295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 35115295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 351205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 351320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 351420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 351520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3517abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 3518abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3519abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3520abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 3521abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 3522abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 3523abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 3524abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3525df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 3526abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 3527abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 3528abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 3529abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 3530abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 3531abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3532abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 353320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 353420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 353520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 353620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 353720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 353820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 353920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 354020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3541c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 35420024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 35434678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t cts; 35448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 3545dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 3546dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 3547dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 354820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3549c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 3550c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 35514678a6dc5f09008481524949a9667af5a6190374Andreas Huber mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 355220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3553dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3554dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3555dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3556dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3557dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 3558c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 3559dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3560ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 3561dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3562dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 35630024245e134467d120b40099da16c467dc365e76Andreas Huber } 356420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3565dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 3566dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 3567dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 356834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 3569dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3570dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 3571dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3572dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3573dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3574dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 3575dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3576dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 35777b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3578dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 3579dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 358048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 35814678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3582abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3583abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3584abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3585abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3586abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3587abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 35888bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 35898bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 35908bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 35918bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 3592dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 3593dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3594dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3595dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 3596dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 3597dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3598dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3599dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3600dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3601dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3602dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 3603dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 3604dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 36056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 3606dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3607dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 3608dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 3609dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 36106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 3611e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 361229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 3613e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3614e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 3615e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 3616e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3617e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 3618e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 3619dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3620dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 36217b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 36226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 3623dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 36247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3625dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 36266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 36276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 3628dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3629dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 3630dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3631dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3632dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3633dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3634dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 3635dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3636dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3637dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 3638dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 3639dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 3640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 3641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 3642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 3643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 3645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 3646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 3648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 364920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 365020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 365120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 365220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 365320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3654dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 365520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 365620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 36606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 3661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 3663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 3664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 3665e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 366734fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 366834fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 366934fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 367034fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 367134fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 367234fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 367334fe252c89e33572d01fea981b58d7b115e76164James Dong } 3674e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 367534fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 367629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 3677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 3678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 3679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 3680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 3682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 3683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 3684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3685dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 3687dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 3692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 3693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 3694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 3695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 3697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 3699dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3700dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 370120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 370248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 37034678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3704abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3705abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3706abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3707abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3708abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3709abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 37108bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 37118bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 37128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 37138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 371420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 371520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 371620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 371720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 371820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 371920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 372020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 372120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 372220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 372305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 372405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 372505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 372605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 372705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 372805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 372905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 373005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 373105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 373205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 373305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 373405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 373505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 373605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 373705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 373805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 373905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 374005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 374105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 374205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 374305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 374405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 374505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 37463f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 374705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 374805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 374905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 375005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 375105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 375205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 375305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 375405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 375505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 375605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 375705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 375805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 3759ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 3760ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 3761ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 3762ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 3763ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 3764ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 3765ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 3766ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 3767ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 3768ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 3769ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 3770ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 3771ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 377205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 377305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 377405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 377505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 377605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 377705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 377805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 377905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 378005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 378105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 378205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 3783442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 378405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 378505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 378605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 378705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 378805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 378905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 379005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 37913f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 37923f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 37933f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 37943f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 3795ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 379605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 379705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 379805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 379905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 3800ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 3801ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 3802ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 380305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 380405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 380505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 380605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 380705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 380805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen cts = mCurrentTime; 380905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 381005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 381105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 381205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 381305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 381405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 381505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 381605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 381705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 381805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 381905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 382005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 382148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 382248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 382348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 382448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 382548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 382648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 382748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 382848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 382948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 383048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 383148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 383248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 383348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 383448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 383548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 383605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mIsAVC || mWantsNALFragments) { 383705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 383805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 383905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 384005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 384105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 384205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 384305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 384405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 384505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 384605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 384705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 384805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 384905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 385005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 385105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 385205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 385305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 385405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 385505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 385605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 385705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 385805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 385905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 386005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 386105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 386205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 386305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 386405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 386505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 386605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mIsAVC) { 386705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 386805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 386905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 387105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 387205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 387405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 387505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 387705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 387805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 387905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 388005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 388105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 388205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() < mNALLengthSize + nal_size) { 388305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 388405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 388505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 388605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 388705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 388805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 388905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 389005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 389105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 389205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 389305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 389405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 389505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 389605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 389705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 389805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 389905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 390105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 390205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 390305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 390605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 390805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 390905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = 391705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 392505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 392705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 392805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 393105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 393205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 393305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 393505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 393605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 393705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 393805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 394005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isMalFormed = (srcOffset + mNALLengthSize > size); 394105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 394205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isMalFormed = srcOffset + nalLength > size; 394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 394705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 394905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("Video is malformed"); 395005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 395105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 395205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 395305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 395605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 395705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(dstOffset + 4 <= mBuffer->size()); 396005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 398705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 398905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 399005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 399205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 399405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3995bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 3996bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 3997bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 3998bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 3999bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4000bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4001bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4002bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4003bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4004bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4005bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4006bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4007bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4008bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 40091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4010693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 401120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 401220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 401420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 401520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 401620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 401720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4019b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4020b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 40210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4022ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4023983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 402418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 40255a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 402620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 402720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 402820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 402920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 403020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 403120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 403220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 40341b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 40351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 40361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 40371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 40381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 40391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 40401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 40414cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 40424cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 40434cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 40444cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 40454cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 404658fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 404758fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 404858fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 40491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 40501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 40511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 40521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 40531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 40541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 40551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 40561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 40571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 40581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 40591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 40601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 40611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 40621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 40631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4064a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4065a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4066a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 40671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4068a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4069a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4070a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4071a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 40721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4073a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4074a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4075a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4076a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 40771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4078a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4079a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4080a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4081a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4082a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4083a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4084a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4085a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4086a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4087a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4088a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4089a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 40901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 40911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 40921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4093a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4094a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4095a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4096a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4097a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4098a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4099a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4100a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4101a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4102a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4103a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4104a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4105a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 4106a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 410705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 410805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 410905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("saw chunk type %s, size %lld @ %lld", chunkstring, chunkSize, offset); 4110a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4111a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4112a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4113a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4114a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4115a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4116a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4117a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4118a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4119a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4120a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4121a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4122a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4123a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4124a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4125a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4126a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4127a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4128a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4129a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4130a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4131a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4132a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4133a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4134a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4135a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4136a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4137a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4138a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4139a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4140a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4141a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4142a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 41431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 41441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4145a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4146a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4147a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4148a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4149a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4150a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4151a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4152a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4153a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4154a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4155a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 41561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4157a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4158a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 41591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 41601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4161a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 41621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 41631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 41641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 41651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 41665a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 41671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4168a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4169a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4170a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4171a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4172456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber ALOGV("found metadata size: %lld", moovAtomEndOffset); 4173a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4174a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 41751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 41761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 41771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 41781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 41795a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4180a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4181a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 41821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 41831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 41841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 41851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 41865ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 41871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 41881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 41891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 41901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 41911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 41921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 419320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 4194