MPEG4Extractor.cpp revision 00307ade843ac9219ffb9a351a3145ec2927ea51
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> 42fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 5048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 5105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 5205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 5305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 6105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 65693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 677b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 70693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 72693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 7505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 7605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 7705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 7805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 7905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 8005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 8105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 84ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 85ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 86ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 87ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 8848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 89ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 90ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 91ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 92ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 93ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 94ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 95ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1070024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1080024245e134467d120b40099da16c467dc365e76Andreas Huber 1096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 11005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 11105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 11205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 11505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 11605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 11705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 11805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 11905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 12005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 12105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 12205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 12305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 12405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 12505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 12605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 12705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 12805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 12905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 13305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 163c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 164c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 167c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 176c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 211c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 223c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 231c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 30018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 30318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 305371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 30618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 307371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 30918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 312e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 313e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 31418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 31718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 320dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 32648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 32748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 32848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 32948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 33048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 33148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 33248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 33348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 33448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 33548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 33648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 33748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 33848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 33948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 340693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 34105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen : mSidxDuration(0), 34205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mMoofOffset(0), 34305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 344bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3457be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 346fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 34872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 349dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 350dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 351dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 363dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 364dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 365dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 366dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 367dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf->IPMPData; 368dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 369dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 370dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 371dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 372ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 373ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 374ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 375ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 37905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 38005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 38105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 38205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 38305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3847be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 3857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 3867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 38772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 3887be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 3897be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 39072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 3917be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 3927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 396ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 407ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: %d tracks", n); 408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4117e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 428371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 429371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 430371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 431371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 43905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 44005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 44105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 44205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 44305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 44405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 44505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 44605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 44705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 44805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 44905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 45005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 45105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 45205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 45305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 45405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 45505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 45605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 46548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 46648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 46748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 46848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 46948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 47048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 47148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 473bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 474bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 477c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 47905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (true) { 48005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 48105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err == OK) { 48205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 48305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 48405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 48505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 48605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(offset, hdr, 8) < 8) { 48705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 48805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 48905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 49005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('s', 'i', 'd', 'x')) { 49105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // parse the sidx box too 49205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 49305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 49405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // store the offset of the first segment 49505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mMoofOffset = offset; 49605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 49705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 4997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 500bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 50172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 502bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 503bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 50472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 50572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 50672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 50772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 5084678a6dc5f09008481524949a9667af5a6190374Andreas Huber mInitCheck = OK; 509bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 510bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 513bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 514ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 515ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 516ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int psshsize = 0; 517ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 518ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 519ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 520ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (psshsize) { 521ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 522ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 523ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 524ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 525ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 526ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 527ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 528ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 531bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 534dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 535dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 536dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 537dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 538dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 539dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 540dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 541dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 542dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 543dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 544dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 545dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 558dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 559dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 560dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 561dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 562dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 563dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 564dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 565dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 566dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 567dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 568dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 569dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 570dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 571dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 572dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 573c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { 574dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 575dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t classSize = size; 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang classSize = size; 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPData = new char[sinf->len]; 685f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 687f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 70372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 70472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 70572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 70672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 70772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 70872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 70972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 71072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 71172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 71272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 71372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 71472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 71572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 71672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 71772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 71872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 71972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 72172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 72272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 72372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 72472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 72572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 72672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 72772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 72872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 72972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 73072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 73172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 73372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 73472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 73572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 73672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 73772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 738c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 7395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("entering parseChunk %lld/%d", *offset, depth); 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 74134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 746c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 74934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 75471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 75571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 75671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 75771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 75871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 75971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 76071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 76171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 76605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth); 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 774ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 775ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 776ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 777ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 778ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 779ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 780ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 782ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 783ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 78772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 788c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 791515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 79272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 793c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 79472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 79572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 79672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 79772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 79872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 79972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 80072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 801bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 802bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 803bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 804bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 80572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 80672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 80772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 80872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 82072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 82172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 822ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 823ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 8240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 82650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 8273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 82850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 829b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 830b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 831b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 83250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 83350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 83450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 83550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 83650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 83750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 83850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 8391edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 8401edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 84150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 84250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 8436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 844bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 8456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 8466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 847bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 848bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 849bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 850bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 851bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 852bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 853bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 854bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 855bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 856bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 857bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 8586f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 859bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 860bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 861bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 862bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 863c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 872bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 873bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 874bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 875bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 8766f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 8776f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 8786f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 8796f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 8806f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 8816f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 8826f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 8836f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 8846f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 8856f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 8866f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 8876f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 8886f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 8896f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 8906f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 8916f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 8926f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 8936f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 8946f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 895bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 896bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 897bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 898bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 899bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 900bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 901bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 903dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 904dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 905dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 906dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 907dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9120a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 9130a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 9140a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 9150a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 9160a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 9170a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 9210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 9220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9250a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 9260a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 9270a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 928fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 929210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 9300a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9310a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 9320a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 9330a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 9340a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9350a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 9360a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 9370a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 9380a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9390a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9400a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 9410a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 9420a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 9430a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 9440a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 9450a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9460a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9470a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 9480a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 9490a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 9500a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 9510a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 953fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 954fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 955fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 9560a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 9580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 9590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 9600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 9610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 9630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 9640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 9650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingus = duration - (segment_duration + media_time); 966465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 967465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 968465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 969465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 970465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 971465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 9720a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 9730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 9740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen *offset += chunk_size; 9770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 9780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 9790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 980ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 981ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 98248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 983ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 984ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 985ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 986ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 987ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 98948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 99048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 99148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 99248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 99348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 99448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 995ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 996ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 997ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 998ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 999ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1000ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 1001ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1002ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1003ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1004ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1005ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1006ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1007ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1008ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1009ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1010ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1011ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1012ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1013ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1014ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1015ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1016ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1017ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1018ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1019ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1020ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1021ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1022ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1023ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1027ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1028ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1036ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1037ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1038ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1039ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 1046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1051ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1052ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1053ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 1062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1066ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1069ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1070ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1071ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1072ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1074ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (pssh.datalen + 20 > chunk_size) { 1075ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1076ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1077ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1078ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1079ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.data = new uint8_t[pssh.datalen]; 1080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1087ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 1088ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 109120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 109220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 109320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 109420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 109520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 109620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 109834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 110020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 110120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1104c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 111534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 111620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 112534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 113205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 113334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 113420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 113520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 113620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 113720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // ffmpeg sets duration to -1, which is incorrect. 113905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 114005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 114105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 114220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 114448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 114520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 11477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 11487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 11497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 11507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 11517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 11527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 11537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 11547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 11557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 11567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 11577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 11587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 11597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 11607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 11617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 11627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 11637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 11647a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 11657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 11667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 11677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 11687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 11697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 11707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 11717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 11727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 117320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 117520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 117920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1184c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1185bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1186bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1187bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 118834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 119620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 12013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 12023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 12033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 12053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 12063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 12093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 12103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 12113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 12123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 12133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1215c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 121620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 121720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 121820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 121920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 122020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 122120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 122220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1223bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1224bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1225bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1226bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 122920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 123148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1233371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 124748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 124820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 125081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 125181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 125248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 125348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 125448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 125548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 125881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1262c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 126520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 126620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1270bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1271bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1272bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1273bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1278ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1280e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1281e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 128320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 12847be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 12857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 128620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 129320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 129920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1301ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1302a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1303a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1304a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1305a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1306a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1307a6256238d9015c42129fe43791968768fe501efaJames Dong 1308134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1309134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 131020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1311ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1312ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1313ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1314ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 131520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 131620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 131720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1318c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 131920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 132020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 132120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 132220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1326bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1327bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1328bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1329bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 133020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 133120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 133520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 133620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 133720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 133820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 133920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 134120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 134220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1373738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 137449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 137549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 137649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 137749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 137849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1379738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 138005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 138105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 138205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 138305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 138405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 138505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 138605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 138705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 138805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t width, height; 1389f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || 1390f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar !mLastTrack->meta->findInt32(kKeyHeight, &height)) { 139105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1392f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1393f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 139405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1395f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 13964256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 13974256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1398f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1399f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // AVC requires compression ratio of at least 2, and uses 1400f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1401f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1402f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1403f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1404f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1405f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 140605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1407f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 140805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 1410113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 14114256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 14124256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1413113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1414113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1415113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1416113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1417113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1418113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1419113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1420113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1421113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1422113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1423113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1424113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1425113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1426113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1427113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 143020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 143220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 143520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 14464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 14474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 14484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 14494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 14504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 14514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 14524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 14534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 14544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 14554931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber *offset += chunk_size; 14564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 14574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 14584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 146620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 146720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 147220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14734948818cb91176df74c972ac27b2f392b5d148bcJames Dong // @xyz 14744948818cb91176df74c972ac27b2f392b5d148bcJames Dong case FOURCC('\xA9', 'x', 'y', 'z'): 14754948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 14764948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Best case the total data length inside "@xyz" box 14774948818cb91176df74c972ac27b2f392b5d148bcJames Dong // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 14784948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 14794948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 14804948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 14814948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 14824948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 14834948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 14844948818cb91176df74c972ac27b2f392b5d148bcJames Dong 14854948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 14864948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 14874948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 14884948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 14894948818cb91176df74c972ac27b2f392b5d148bcJames Dong 14904948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 14914948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 14924948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 14934948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 14944948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 14954948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 14964948818cb91176df74c972ac27b2f392b5d148bcJames Dong 14974948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 14984948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 14994948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 15004948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15014948818cb91176df74c972ac27b2f392b5d148bcJames Dong 15024948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 15034948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 15044948818cb91176df74c972ac27b2f392b5d148bcJames Dong *offset += chunk_size; 15054948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 15064948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 15074948818cb91176df74c972ac27b2f392b5d148bcJames Dong 150820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 150920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 151020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 151120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 151220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1515c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 151620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 152020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 152120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 152220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 152620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 153020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1532ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1533ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1534ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1535ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1536ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1537ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1538ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1539ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1540ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1541ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1542ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1543ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1544ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1545ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1546ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 154720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 154920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 155020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 155120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 155220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1553d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 155420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 155534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1556d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 155720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 155820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 155920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 156020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1561d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 156220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 156320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1567244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1568244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 156917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 157017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 157117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 157217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 157317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 157417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 157517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 157617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 157717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 157817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 157917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 158017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 158117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 158217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 158329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1584244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1585244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1586244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1587244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1588244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1589244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1590244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1591244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1592244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1593244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1594244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong *offset += chunk_size; 1595244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1596244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1597244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 159872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 159972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 160072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1601c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1602bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1603bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1604bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 160572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 160672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 160772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 160872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 160972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 161072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 161172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1612ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1613ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1614ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1615ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1616ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1617ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1618ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 161972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 162072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1621c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 162272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 162372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 162472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 162572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 162672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 162772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 162872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1629bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1630bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1631bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1632bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 163372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 163472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 163572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 16365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 16375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 163872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 163972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 164072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1641fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 164272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 164372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 164472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 164572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 164672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 164772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 164872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 164972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 165072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 165172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 165272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 165372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 1654fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen if (chunk_data_size < 24) { 165572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 165672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 165772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1658fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint8_t header[24]; 165972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 166072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 166172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 166272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 166372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 166472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1665fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 166672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 166772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1668fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1669bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1670bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 167172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 167272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1673fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 167472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 167572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 167672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 167772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 167872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 167972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 168072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 168172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 168272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 168372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 168472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1687ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 1688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 17003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 17013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 17023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 17033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 17043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 17053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 17063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 17093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1710e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1711e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1712e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 17133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 17143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 17173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 17183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 17217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 17223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 17233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 17243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 17253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 17263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 17273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 17283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint8_t *buffer = new uint8_t[size + chunk_size]; 17313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 17333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 17343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 17373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 17383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 17393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 17403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 17423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 17433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 17453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 17463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 17473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 17487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 17497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 17507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 17517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 17527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 1753515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 1754515e855eae78aa495da58356486aaa666cb57fd1James Dong { 1755515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 17563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("chunk_data_size = %lld and data_offset = %lld", 1757515e855eae78aa495da58356486aaa666cb57fd1James Dong chunk_data_size, data_offset); 17581552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 1759515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 17601552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 1761515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 1762515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1763515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 1764515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 1765515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 17661552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1767515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1768515e855eae78aa495da58356486aaa666cb57fd1James Dong 1769515e855eae78aa495da58356486aaa666cb57fd1James Dong *offset += chunk_size; 1770515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 1771515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1772515e855eae78aa495da58356486aaa666cb57fd1James Dong 1773fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 1774fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 1775fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 1776fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 1777fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 1778fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 1779fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 1780fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 1781fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1782fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 1783fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 1784fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 1785fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 1786fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé *offset += chunk_size; 1787fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 1788fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 1789fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 17905d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 17915d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 17925d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 17935d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 17945d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 17955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 17965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 17975d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 17985d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 179905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 180005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 180105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 180205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 180305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 180405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 180505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 180820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 181020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 181420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 181520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 181705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 181805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 181905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 182005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 182105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 182205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 182305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 182405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 182505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 182605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 182705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 182805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 182905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 183005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 183105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 183205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 183305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 183405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 183505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 183605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 183705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 183805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 183905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 184005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 184105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 184205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 184305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 184405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 184505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 184605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 184705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 184805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 184905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 185005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 185105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 185205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 185305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 185405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 185505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 185605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 185705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 185805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 185905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 186005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 186105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 186205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 186305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 186405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 186505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 186605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 186705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 186805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 186905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 187005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 187105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 187205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 187305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 187405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 187505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 187605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 187705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 187805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset); 187905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 188005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 188105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 188205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 188305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 188405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 188505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 188605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 188705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 188805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 188905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 189005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 189105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 189205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 189305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 189405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 189505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 189605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 189705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 189805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 189905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 190005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 190105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 190205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 190305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 190405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 190505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 190605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 190705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 190805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 190905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 191005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool saptype = d3 >> 28; 191105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!sap || saptype > 2) { 191205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("not a stream access point, or unsupported type"); 191305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 191405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 191505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 191605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 191705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 191805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 191905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 192005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 192105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 192205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 192305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxDuration = total_duration * 1000000 / timeScale; 192405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("duration: %lld", mSidxDuration); 192505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 192605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 192705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 192805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt64(kKeyDuration, mSidxDuration); 192905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 193005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 193105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 193205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 193305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 193405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 1935ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1936c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 1937ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1938ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1939ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1940ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1941ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1942ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1943ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1944ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1945ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1946ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1947ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1948ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1949ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1950c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 1951ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1952ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1953ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1954ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1955ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1956ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1957ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1958ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1959ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 1960ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 1961ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1962ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 1963ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 1964ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 1965ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 1966ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 196704022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 1968ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 1969ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 1970ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 1971ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 197204022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 197304022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 1974ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1975ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1976ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1977ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1978ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 1979ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1980ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1981ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1982ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1983ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1984ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1985ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1986ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1987df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 1988ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1989df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 1990ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1991ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1992ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1993ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 1994ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1995ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 1996ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1997ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 1998ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1999ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2000ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2001ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2002ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2003ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2004ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2005ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 20065ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2007ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2008ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2009ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2010ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2011ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2012ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2013ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2014b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2015b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2016ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2017ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2018b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2019b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2020ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2021ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2022ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2023ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2024fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 202572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 202672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 202772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 202872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 202972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 203072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 203172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 203272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 203372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 203472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 203572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 203672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 203772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 203872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 203972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 204072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 20415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 20425d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 20435d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("meta: %s @ %lld", chunk, offset); 204472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 204572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 204672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 204772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 204872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 204972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 205072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 205172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 205272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 205372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 205472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 205566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 205666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 205766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 205866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 205966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 206072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 206172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 206272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 206372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 206472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 206572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 206672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 206772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 206872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 206972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 207072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 207172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 207272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 207372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 207472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 207572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 207672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 207772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 207872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 207972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 208072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 208172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 208272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 208372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 208472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 208526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 208626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 208726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 208826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 208926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 209011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 209111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 209211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 209311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 209411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 209511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 209611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 209711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 209811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 209911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 210011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 210172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 210272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 210372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 210472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2105afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2106afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2107afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 210872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 210972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 211072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 211172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 211272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 211326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 211426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2115afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 211626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2117afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2118afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2119afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 212026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 212126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 212226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 212326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 212426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 21255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 21265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 21275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 21285d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 21295d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 21305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 21315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 21335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 21345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 21365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 21375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 21398c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 21408c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 21418c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 21428c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 21438c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 21448c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 21458c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 21468c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 21478c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 21488c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 21498c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 21508c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 21518c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 21528c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 21538c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 21548c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 21558c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 21568c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 21575d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 21588c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 21595d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 21605d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 21615d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 21625d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 21635d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 21645d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 216526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 216672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 216772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 216872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 216972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 217072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 217172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 217272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 217372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 217472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 217572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 217672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 217726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 217826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 217926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 218026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 218126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 218226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 218326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 218426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 218526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 218672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 218726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 218872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 218972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 219026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 219126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 219226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 219326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 219426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 219526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 219672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 219772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 219872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 219972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 220072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 220172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 220272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 220372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 220472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 220572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 220672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 220772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 220872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 220972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 221072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2211fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 2212fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size < 4) { 2213fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2214fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2215fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2216fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint8_t *buffer = new uint8_t[size]; 2217fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2218fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2219fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2220fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2221fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2222fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2223fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2224fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2225fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2226fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2227fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2228fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2229fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2230fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2231fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2232fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2233fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2234fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2235fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2236fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2237fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2238fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2239fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2240fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2241fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2242fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2243fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2244fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2245fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2246fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2247fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2248fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2249fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2250fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2251fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2252fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2253fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2254fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2255fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2256fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2257fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2258fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2259fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2260fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2261fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2262fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2263fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2264fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2265fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2266fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2267fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2268fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2269fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2270fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2271fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2272fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2273fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2274fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2275fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2276fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2277fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2278fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2279fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2280fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2281fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 2282fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2283fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2284fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2285fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2286fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2287fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2288fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2289fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2290fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2291fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2292fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2293fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2294fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2295fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2296fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2297fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2298fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2299fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2300fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2301fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2302fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2303fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2304fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 2305fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2306fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2307fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2308fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2309fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2310fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2311fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2312fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2313fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2314fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2315fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2316fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2317fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2318fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 232020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 232120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 232320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 232420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 232520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 232620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 232720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 232920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 233020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 233120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 233220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 233320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 233420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2335371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 2336371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 2337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 2338371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2339ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("getTrack called, pssh: %d", mPssh.size()); 2340ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 234205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 234305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries, mMoofOffset); 234420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 234520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2346bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 2347bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 2348bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 2349bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2350bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2351bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 2352bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 2353bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 2354bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2355bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2356bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 2357bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2358bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2359bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2360bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2361bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2362bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 2363bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2364bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2365bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 2366bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2367169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber if (!track->sampleTable->isValid()) { 2368169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 2369169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 2370169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 2371169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 2372bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 2373bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 2374bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2375ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 2376ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 2377ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 237881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 237981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 238081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 238181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 238281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 238381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 238481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 238581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 238681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 238781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 238881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 238981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 2390633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 2391633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 2392633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 2393633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 239429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 2395633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 2396633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 2397633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 2398ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 2399ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 2400ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 2401ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 2402ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2403ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2404ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2405ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 2406ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 2407ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 2408ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 2409ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2410a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 2411a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 2412a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 2413a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 2414a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2415a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 2416a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 2417a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 2418ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 2419ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2420ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2421ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 242200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 242300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 242400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 242500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 242600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 2427aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 2428aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 2429ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2430aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 2431aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 2432ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2433ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2434aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 2435aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 2436ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 2437ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 2438ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 2439ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 2440ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 2441ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2442aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 2443aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 2444ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 2445595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 244600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 244700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 244800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 2449ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2450ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 245100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 245200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 2453595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 245400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (objectType == 5 || objectType == 29) { // SBR specific config per 14496-3 table 1.13 245500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 245600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent int32_t extSampleRate; 245700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 245800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 2459595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 2460595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 246100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 246200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 246300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 246400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 246500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 246600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 2467595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 246800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 246900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 2470ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2471ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2472ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 2473ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 2474ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2475ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2476ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 2477ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 2478ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2479ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 24803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 2481ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 2482ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2483ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2484ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 2485ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2486ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 2487ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 2488ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2489ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 24903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 2491ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 2492ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 2493ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2494ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 2495ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 2496ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 2497ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 2498ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 249920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 250020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 250120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 250220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 2503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 250448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 250505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 250605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 250705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 250820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 250920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 251048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 251120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 251220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 251305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 251405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 251505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 251605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 251705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 2518ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 2519ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 2520ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 2521ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 252220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 25236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 252420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 252520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 252620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 2527dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 25280024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 2529ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2530ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 253148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 2532ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 2533ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 2534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 2535ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 2536ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 2537ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 2538ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 2539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 2540ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2541ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 254220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 254320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 2544dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 254520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 254618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 25476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 25486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 25496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 25506064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 25516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 25526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 25536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 25546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 25556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 25566064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 2557ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 25586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 25596064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 25606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 25616064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 256205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 256305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 256405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 256505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 256605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 256705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 256805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 256920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 257020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 257120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 257220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 257320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 257420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 2575ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 2576ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 257720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 257820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 257920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 25807b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 25817b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 2582dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 258320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 258420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 2585dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 258620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 2587dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 258820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 2589dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 259020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 259120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 259220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 259320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2594738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 2595738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 259620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2597738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 25980024245e134467d120b40099da16c467dc365e76Andreas Huber 25990024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 260020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 260120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 260220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 260320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 260420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 260520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 260620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 26077b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 26087b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 2609dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 261020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 261120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 261220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 261320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 261420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 261520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26160024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 26170024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 26180024245e134467d120b40099da16c467dc365e76Andreas Huber 261920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 262020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 262120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 262220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 262320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 262420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 262520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 262620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 262720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 262805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 262905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 263005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 263105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 263205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 263305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 263405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 263505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 263605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 263705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 263805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 263905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 264005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 264105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 264205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 264305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 264405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 264505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 264605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 264705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 264805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 264905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 265005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 265105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 265205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 265305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 265405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 265505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset); 265605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 265705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 265805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 265905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 266005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 266105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 266205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 266305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 266405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 266505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 266605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 266705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 266805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 266905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 267005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 267105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 2672ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // *offset points to the mdat box following this moof 267305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(offset); // doesn't actually parse it, just updates offset 267405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mNextMoofOffset = *offset; 267505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 267605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 267705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 267805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 267905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 268005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 268105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 268205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 268305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 268405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 268505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 268605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 268705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 268805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 268905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 269005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 269105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 269205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 269305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 269405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 269505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 269605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 269705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 269805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 269905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2700ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 2701ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 2702ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 2703ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 2704ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2705ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 2706ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 2707ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2708ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 2709ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 2710ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 2711ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 2712ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2713ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 2714ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 2715ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2716ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2717ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 2718ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 2719ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 2720ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 2721ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 2722ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 2723ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2724ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 272505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 272605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 272705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 272805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 272905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 273005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 273105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 273205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissenstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size) { 2734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 2735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 2736ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 2737ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 2738ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 2739ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 2740ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2741ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2742ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2743ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 2744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 2745ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2746ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 2747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2748ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 2749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 2750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2752ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 2753ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2754ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 2755ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 2756ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 2757ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 2758ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2759ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 2760ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 2761ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 2762ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 2763ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2764ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 2765ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 2766ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2767ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2768ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 2769ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 2770ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 2771ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2772ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 2773ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 2774ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2775ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 2776ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 2777ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 2778ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 277948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 2780ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 2781ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 278248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 278348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 278448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 278548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 2786ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 2787ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 2788ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 2789ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2790ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2791ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 2792ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 2793ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 2794ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2795ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissenstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size) { 2796ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 2797ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 2798ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 2799ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 2800ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2801ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2802ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 2803ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2804ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 2805ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 2806ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2807ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2808ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 2809ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2810ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 2811ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 2812ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2813ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2814ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 2815ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2816ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 2817ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8); 2818ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 2819ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2820ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 2821ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2822ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 2823ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 2824ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 2825ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 2826ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2827ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2828ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 2829ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 2830ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 2831ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 2832ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 2833ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2834ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2835ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 2836ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 2837ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2838ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2839ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2840ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 2841ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2842ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 2843ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2844ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 2845ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 2846ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 284748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 284848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 2849ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 2850ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 2851ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2852ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 2853ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 2854ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2855ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2856ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2857ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 2858ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 285948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 286048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 286148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 2862ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 286348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 286448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 286548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 2866ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 2867ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2868ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 286948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 287048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 287148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 287248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 287348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 287448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 287548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 287648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 287748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 287848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 287948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 288048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 288148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 2882ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 288348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 288448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 288548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 2886ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2887ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 2888ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2889ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2890ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 2891ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 2892ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 289305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 289405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 289505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 289605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 289705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 289805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 289905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 2900ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 290105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 290205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 290305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 290405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 290505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 290605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 290705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 290805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 290905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 291005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 291105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 291205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 291305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 291405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 291505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 291605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 291705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 291805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 291905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 292005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 292105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 292205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 292305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 292405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 292505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 292605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 292705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 292805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 292905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 293005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 293105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 293205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 293305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 293405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 293505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 293605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 293705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 293805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 293905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 294005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 294105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 294205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 294305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 294405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 294505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 294605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 294705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 294805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 294905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 295005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 295105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 295205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 295305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 295405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 295505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 295605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 295705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 295805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 295905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 296005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 296105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 296205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 296305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 296405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 296505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 296605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 296705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 296805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 296905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 297005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 297105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 297205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 297305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 297405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 297505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 297605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 297705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 297805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 297905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 298005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 298105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 298205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 298305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 298405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 298505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 298605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 298705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 298805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 298905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 299005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 299105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 299205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 299305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 299405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 299505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 299605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 299705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 299805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 299905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 300005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 300105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 300205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 300305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 300405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 300505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 300605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 300705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 300805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 300905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 301005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 301105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 301205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 301305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 301405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 301505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 301605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 301705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 301805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 301905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 302005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 302105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 302205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 302305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 302405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 302505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 302605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 302705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 302805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 302905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 303005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 303105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 303205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 303305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 303405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 303505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 303605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 303705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 303805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 303905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 304005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 304105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 304205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 304305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 304405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 304505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 304605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 304705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 304805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 304905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 305005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 305105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 305205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 305305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 305405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 305505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 305605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 305705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 305805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 305905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 306005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 306105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 306205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 306305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 306405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 306505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 306605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 306705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 306805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 306905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 307005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 307105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 307205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 307305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 307405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 307505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 307605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 307705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 307805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 307905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 308005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 308105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 308205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 308305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 308405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 308505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 308605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 308705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 308805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 308905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 309005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 309105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 309205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 309305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 309405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 309505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 309605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 309705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 309805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 309905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < sampleCount * bytesPerSample) { 310005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 310105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 310205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 310305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 310405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 310505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 310605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 310705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 310805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 310905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 311005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 311105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 311205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 311305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 311405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 311505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 311605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 311705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 311805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 311905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 312005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 312105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 312205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 312305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 312405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 312505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 312605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 312705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 312805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 312905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 313005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 313105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 313205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("adding sample %d at offset 0x%08llx, size %u, duration %u, " 3134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 313505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 313605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 313705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 313805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 313905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 314005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 314105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 314205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 314305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 314405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 314505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 314605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 314705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 314805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 314905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 315005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 315120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 31527b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 31537b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 315420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 315520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 315620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 31586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 31596064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 31606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 31616064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 31626064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 31636064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 31646064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 31656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 31666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 31676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 31686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 31696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 31706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 31716064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 31726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 31736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 31746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 31756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 317620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 317720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 31787b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 31797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3180dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 318120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 318205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 318305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 318405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 318505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 318620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 318720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3188abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 3189abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 319020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 3191abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 3192abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3193abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 3194abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 3195abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 3196abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3197abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3198abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 3199abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 3200abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3201abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 3202abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 3203abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 3204abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3205abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 3206abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 3207abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 3208abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3209abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 321020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 3211abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 321220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 3213abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 3214abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3215abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3216abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 3217abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 3218abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 3219abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 3220abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3221abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3222abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 3223abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 3224abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 3225abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 3226abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 322720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3228788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 3229788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 3230788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 3231788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 3232788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 3233788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 323420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 32355295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 32365295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 32375295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 32385295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 32395295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 32405295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 32415295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 32425295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 324305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 324420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 324520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 324620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3247abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 3248abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 3249abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3250abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3251abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 3252abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 3253abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 3254abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 3255abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3256df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 3257abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 3258abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 3259abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 3260abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 3261abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 3262abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3263abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 326420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 326520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 326620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 326720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 326820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 326920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 327020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 327120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3272c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 32730024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 32744678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t cts; 32758bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 3276dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 3277dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 3278dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 327920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3280c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 3281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 32824678a6dc5f09008481524949a9667af5a6190374Andreas Huber mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 328320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3284dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3285dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3286dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3287dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3288dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 3289c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 3290dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 3291ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 3292dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 3293dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 32940024245e134467d120b40099da16c467dc365e76Andreas Huber } 329520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3296dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 3297dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 3298dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 329934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 3300dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3301dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 3302dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3303dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3304dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3305dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 3306dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3307dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 33087b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3309dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 3310dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 331148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 33124678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3313abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3314abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3315abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3316abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3317abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3318abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 33198bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 33208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 33218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 33228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 3323dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 3324dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3325dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3326dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 3327dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 3328dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3329dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3330dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3331dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3332dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3333dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 3334dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 3335dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 33366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 3337dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3338dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 3339dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 3340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 33416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 3342e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 334329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 3344e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3345e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 3346e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 3347e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3348e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 3349e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 3350dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3351dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 33527b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 33536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 3354dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 33557b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 3356dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 33576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 33586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 3359dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3360dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 3361dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 3362dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 3363dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3364dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3365dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 3366dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3367dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 3368dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 3369dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 3370dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 3371dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 3372dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 3373dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 3374dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3375dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 3376dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 3377dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3378dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 3379dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 338020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 338120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 338220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 338320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 338420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3385dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 338620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 338720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 3389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 33916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 3392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 3393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 3394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 3395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 3396e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 3397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 339834fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 339934fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 340034fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 340134fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 340234fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 340334fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 340434fe252c89e33572d01fea981b58d7b115e76164James Dong } 3405e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 340634fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 340729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 3408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 3409dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 3410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 3411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3412dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 3413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 3414dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 3415dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3416dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3417dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 3418dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 3419dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3420dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3421dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 3422dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 3423dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 3424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 3425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 3426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 3427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 3428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 3429dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 3430dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 3431dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 343220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 343348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 34344678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3435abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 3436abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 3437abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 3438abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 3439abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 3440abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 34418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 34428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 34438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 34448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 344520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 344620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 344720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 344820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 344920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 345020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 345120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 345220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 345320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 345405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 345505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 345605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 345805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 345905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 346005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 346205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 346405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 346605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 346705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 346805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 346905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 347005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 347105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 347205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 347305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 347405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 347505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 347605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 347705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC) || 347805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 347905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 348005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 348105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 348205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 348305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 348405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 348505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 348605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 348705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 348805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 348905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 349005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = totalOffset; 349105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 349205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 349305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&totalOffset); 349405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 349505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 349605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 349705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 349805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 349905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 350005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 350105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 350205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 350305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 350405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 350505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 350605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 350705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 350805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 350905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 351005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 351105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 351205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 351305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 351405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // move to next fragment 351505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample lastSample = mCurrentSamples[mCurrentSamples.size() - 1]; 351605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t nextMoof = mNextMoofOffset; // lastSample.offset + lastSample.size; 351705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 351805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 351905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 352005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 352105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 352205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_END_OF_STREAM; 352305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 352705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 352805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 352905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen cts = mCurrentTime; 353005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 353105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 353205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 353405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 353605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 353705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 353805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 353905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 354105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 354248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 354348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 354448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 354548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 354648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 354748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 354848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 354948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 355048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 355148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 355248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 355348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 355448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 355548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 355648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 355705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mIsAVC || mWantsNALFragments) { 355805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 355905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 356005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 356105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 356205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 356305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 356405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 356505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 356605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 356705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 356805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 356905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 357005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 357105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 357205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 357305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 357405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 357505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 357605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 357705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 357805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 357905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 358105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 358205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 358505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 358605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 358705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mIsAVC) { 358805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 358905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 359005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 359205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 359305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 359505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 359605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 359805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 359905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 360005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 360105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 360305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() < mNALLengthSize + nal_size) { 360405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 360505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 360705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 360805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 361005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 361305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 362205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 363005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 363105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 363605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 363705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = 363805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 363905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 364005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 364105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 364205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 364405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 364505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 364605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("i/o error"); 364805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 364905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 365105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 365205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 365305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 365405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 365505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 365605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 365705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 365805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 365905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 366005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 366105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isMalFormed = (srcOffset + mNALLengthSize > size); 366205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 366305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 366405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 366505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 366605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isMalFormed = srcOffset + nalLength > size; 366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("Video is malformed"); 367105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 367205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 367305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 367405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(dstOffset + 4 <= mBuffer->size()); 368105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 368305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 368405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 368505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 368605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 368705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 368805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 368905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 369105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 369205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 369305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 369505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 369605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 369705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 369805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 369905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 370005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 370105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 370205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 370405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 370505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 370605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 370805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 370905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 371005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 371105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 371205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 371305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 371405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 371505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3716bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 3717bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 3718bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 3719bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 3720bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 3721bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 3722bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 3723bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 3724bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 3725bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 3726bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 3727bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 3728bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 3729bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 37301b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 3731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 373220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 373320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 373434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 373520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 373620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 373720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 373820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 373920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 3740b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 3741b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 37420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 3743ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 3744983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 374518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 37465a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 374720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 374820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 374920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 375020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 375120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 375220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 375320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 37551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 37561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 37571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 37581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 37591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 37601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 37611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 37624cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 37634cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 37644cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 37654cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 37664cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 376758fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 376858fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 376958fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 37701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 37711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 37721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 37731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 37741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 37751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 37761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 37771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 37781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 37791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 37801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 37811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 37821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 37831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 37841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 3785a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 3786a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 3787a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 37881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 3789a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 3790a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 3791a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 3792a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 37931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 3794a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 3795a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 3796a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 3797a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 37981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 3799a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 3800a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 3801a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 3802a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 3803a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3804a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3805a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 3806a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 3807a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 3808a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3809a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 3810a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 38111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 38121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 38131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 3814a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 3815a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 3816a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3817a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 3818a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 3819a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 3820a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3821a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 3822a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 3823a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 3824a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3825a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3826a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 3827a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 382805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 382905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 383005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("saw chunk type %s, size %lld @ %lld", chunkstring, chunkSize, offset); 3831a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 3832a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 3833a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 3834a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 3835a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 3836a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3837a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3838a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 3839a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 3840a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 3841a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 3842a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 3843a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 3844a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3845a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3846a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 3847a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 3848a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 3849a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 3850a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3851a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3852a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 3853a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3854a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 3855a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 3856a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 3857a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3858a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3859a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3860a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 3861a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 3862a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3863a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 38641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 38651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 3866a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3867a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 3868a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 3869a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 3870a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3871a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 3872a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 3873a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3874a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3875a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 3876a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 38771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 3878a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3879a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 38801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 38811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 3882a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 38831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 38841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 38851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 38861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 38875a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 38881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 3889a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 3890a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 3891a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 3892a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 3893456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber ALOGV("found metadata size: %lld", moovAtomEndOffset); 3894a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 3895a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 38961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 38971b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 38981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 38991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 39005a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 3901a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 3902a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 39031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 39041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 39051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 39061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 39075ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 39081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 39091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 39101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 39111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 39121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 39131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 391420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 3915