MPEG4Extractor.cpp revision 2fae4e4cb6b3039f28810e827de75b0612fadd83
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen//#define LOG_NDEBUG 0 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1989e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <utils/Log.h> 27a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 28a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/MPEG4Extractor.h" 29a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/SampleTable.h" 30a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/ESDS.h" 31a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ABitReader.h> 33d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson#include <media/stagefright/foundation/ABuffer.h> 34ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 35a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 36bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 3758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar#include <media/stagefright/foundation/ColorUtils.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 4018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h> 46328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h" 47fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 48937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#ifndef UINT32_MAX 49937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#define UINT32_MAX (4294967295U) 50937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#endif 51937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 540dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnarenum { 550dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar // max track header chunk to return 560dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar kMaxTrackHeaderSize = 32, 572fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen 582fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen // maximum size of an atom. Some atoms can be bigger according to the spec, 592fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen // but we only allow up to this size. 602fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen kMaxAtomSize = 64 * 1024 * 1024, 610dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar}; 620dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 66942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen MPEG4Source(const sp<MPEG4Extractor> &owner, 67942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MetaData> &format, 68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 6948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 7005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 7105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 72c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 7305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 8105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 84693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 85693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 877b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 887b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 89942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen // keep the MPEG4Extractor around, since we're referencing its data 90942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen sp<MPEG4Extractor> mOwner; 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 92693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 94693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 9605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 9705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 98c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *mTrex; 9905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 10005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 10105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 10205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 10305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 10405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 11148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 116ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 1203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar bool mIsHEVC; 1216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 1226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1310024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1320024245e134467d120b40099da16c467dc365e76Andreas Huber 1336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 13405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 15105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 15205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 15305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 15405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 15705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 15805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 15905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 16005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 16105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 16205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 16305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 16405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 16505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 166c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t compositionOffset; 167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 17005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 17105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 188c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 189c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 192c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 201c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 236c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 239bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar if (isInRange(mCachedOffset, mCachedSize, offset, size)) { 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 247c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 255c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 26850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 27050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 27250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 27350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 27550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 27650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 27850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 27950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 28050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 28150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 282b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false; 283b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 288377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 32618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 32918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 331371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 33218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 333371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 33518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 338e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 339e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 34018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 34318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 349dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 35548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 35648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 35748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 35848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 35948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 36048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 36148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 36248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 36348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 36448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 36548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 36648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 36748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 36848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 369693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 370c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 371928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound(false), 372928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound(false), 37305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 374bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3757be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 376fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 37872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 379dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 380dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 381dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 3978da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 400dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 402ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 403ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 404ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 405ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 40905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 41005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 41105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 41205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 41305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 4157be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 4167be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 41772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4187be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4197be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 42072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4217be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4227be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 426ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 437a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 458371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 459371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 460371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 461371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 46905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 47005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 47105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 47305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 47405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 47505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 47605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 47705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 47805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 47905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 48005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 48105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 48205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 48305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 48405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 48505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 48605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4877e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4880dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 4890dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar // MPEG2 tracks do not provide CSD, so read the stream header 4900dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) { 4910dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar off64_t offset; 4920dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar size_t size; 4930dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (track->sampleTable->getMetaDataForSample( 4940dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) { 4950dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (size > kMaxTrackHeaderSize) { 4960dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar size = kMaxTrackHeaderSize; 4970dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 4980dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar uint8_t header[kMaxTrackHeaderSize]; 4990dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) { 5000dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar track->meta->setData(kKeyStreamHeader, 'mdat', header, size); 5010dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 5020dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 5030dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 5047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 51148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 51248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 51348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 51448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 51548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 51648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 51748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 519bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 520bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 523c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 525928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang bool sawMoovOrSidx = false; 526928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 527928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) { 528a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 52905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 530a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 5314ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 5324ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 5334ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 534a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 535a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 536ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset); 537a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 538a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 539928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } else if (err == UNKNOWN_ERROR) { 540928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang sawMoovOrSidx = true; 54105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5437be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 544bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 54572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 546bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 547bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 54872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 54972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 55072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 551bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 552bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 555bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 556ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 557ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 558c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen uint64_t psshsize = 0; 559ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 560ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 561ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 562c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (psshsize > 0 && psshsize <= UINT32_MAX) { 563ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 5646a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (!buf) { 5656a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 5666a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 5676a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 568ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 569ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 570ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 571ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 572ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 573ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 574ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 575ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 576ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 577bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 59956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 61984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 62084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 725dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 727dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 728dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 7298da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 7308da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 7318da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 7328da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 733f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 734dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 735f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 736dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 737dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 738dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 739dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 740dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 741dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 747dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 748dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 749dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 750dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 75172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 75272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 75372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 75472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 75572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 75672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 76372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 76572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 76672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 76772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 76972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 77072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 77172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 77272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 77372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 77472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 77572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 7768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) { 7778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return path.size() >= 2 7788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[0] == FOURCC('m', 'o', 'o', 'v') 7798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[1] == FOURCC('m', 'e', 't', 'a') 7808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && (depth == 2 7818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || (depth == 3 782ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang && (path[2] == FOURCC('h', 'd', 'l', 'r') 783ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang || path[2] == FOURCC('i', 'l', 's', 't') 7848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || path[2] == FOURCC('k', 'e', 'y', 's')))); 7858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 7868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 78772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 7883724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissenstatic bool convertTimeToDate(int64_t time_1904, String8 *s) { 7893724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen // delta between mpeg4 time and unix epoch time 7903724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen static const int64_t delta = (((66 * 365 + 17) * 24) * 3600); 7913724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (time_1904 < INT64_MIN + delta) { 7923724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return false; 7933724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 7943724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen time_t time_1970 = time_1904 - delta; 79572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 79672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 7973724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen struct tm* tm = gmtime(&time_1970); 7983724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (tm != NULL && 7993724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) { 8003724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen s->setTo(tmp); 8013724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return true; 8023724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 8033724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return false; 80472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 80572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 806c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 807ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth); 808452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 809452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (*offset < 0) { 810452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 811452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 812452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 81434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 8182d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer int32_t chunk_type = ntohl(hdr[1]); 819c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 82234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 82771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 82871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 82971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 83071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 83171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 832a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 833a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 834a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 835a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 836a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 837a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 838a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 839a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 840a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 841a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 842a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 843a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 844a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 845a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 846a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 847a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 84871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 84971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 850a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 85171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 856ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth); 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 858b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 859b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe static const char kWhitespace[] = " "; 860b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 861b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 863b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe char buffer[256]; 864b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t n = chunk_size; 865b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (n > sizeof(buffer)) { 866b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe n = sizeof(buffer); 867b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 868b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (mDataSource->readAt(*offset, buffer, n) 869b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe < (ssize_t)n) { 870b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return ERROR_IO; 871b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 872ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 873b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(buffer, n); 874b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 87772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 878452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - *offset) is either 8 or 16 879452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunk_data_size = chunk_size - (data_offset - *offset); 880452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunk_data_size < 0) { 881452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 882452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 883452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 8842fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) { 8852fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen char errMsg[100]; 8862fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size); 8872fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen ALOGE("%s (b/28615448)", errMsg); 8882fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg)); 8892fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen return ERROR_MALFORMED; 8902fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen } 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 893515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 89472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 895c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 89672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 89772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 89872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 89972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 90072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 90172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 90272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 903bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 904bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 905bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 906bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 90772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 90872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 90972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 91072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 91420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 92272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 92372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 924ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 925ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 9260a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 928928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) { 929928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang // store the offset of the first segment 930928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound = true; 931928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofOffset = *offset; 932928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } 933928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 93450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 935a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 93650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 937b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 938b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 939b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 94050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 94150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 94250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 94350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 94450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 94550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 94650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 9471edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 948f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 949f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 950f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 9511edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 95250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 95350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9546f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 955bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 9566f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 9576f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 958bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 959bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 960bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 961bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 962bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 963bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 964bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 965bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 966bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 967bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 968bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 9696f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 970bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 971bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 972bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 973bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 974c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 97620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 983bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 985bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 986bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 9876f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 9880386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia int32_t trackId; 9890386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia // There must be exact one track header per track. 9900386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 9910386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia mLastTrack->skipTrack = true; 9920386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } 9936f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 9946f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 9956f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9966f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 9976f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 9986f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 9996f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 10006f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 10016f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 10026f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 10036f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 10046f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 10056f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 10066f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 10076f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 10086f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 10096f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 10106f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 1011bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 1012bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1013bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 1014bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 1015bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1016bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 1017bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1019dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1020dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 1021dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1022dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 1023dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 102520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 102620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 102720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10280a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 10290a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 10300517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10310517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 10320a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 10330a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 10340a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 10350a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10360a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10370a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10380a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 10390a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 10400a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10410a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10420a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10430a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 10440a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 10450a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 1046fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 1047210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 10480a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10490a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 10500a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 10510a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 10520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 10540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 10550a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 10560a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 10590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 10600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 10610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 10620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 10630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 10660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 10670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1071fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 1072fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 1073fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 10740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 10760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 10771391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 10781391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 10791391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 10800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 10810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 10820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 10840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 10850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1086608fe1d6b2ea4d88245a109afe2bfba580881a16Wei Jia int64_t paddingus = duration - (int64_t)(segment_duration + media_time); 1087465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1088465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1089465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1090465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1091465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1092465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 10930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 10940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 10950a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10960a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10970a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 10980a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11020517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11030517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 110448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1110f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1111f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1112f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1113f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 111548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 111648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 111748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 111848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 111948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 112048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1161ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1166ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1169f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1170f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1171f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1173ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1174ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1175ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1176ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1177ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 117920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11800517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11810517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1182ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1183ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1184ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1190ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1191ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11930517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1194ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1195ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1196ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1197ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1198ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1200ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1201ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1202ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1203ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1205ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1206c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (chunk_size < 20 || pssh.datalen > chunk_size - 20) { 1207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1209ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1210ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 12118da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 12128da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 12138da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 12148da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1215ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1216ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1217ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1218ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1219ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1220ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1221ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1222ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1223ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1224ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 12270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 12280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1229202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 123434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1240c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 124620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 124720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 124820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 125134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 125320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 125420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 125520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12572e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (!timescale) { 12582e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale should not be ZERO."); 12592e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 12602e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 12612e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1264c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1265c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 126605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 126834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1273c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1274c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1275c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 127705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 127834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 128120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 128405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 128505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 128620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1287e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mLastTrack->timescale != 0) { 1288c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1289c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1290c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 129120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 12937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 12947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 12957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 12967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 12977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 12987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 12997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 13007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 13017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 13037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 13047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 13057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 13067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 13087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 13097a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 13107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 13117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 13127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 13137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 13147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 13157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 13177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 13187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 131920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 132020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 132220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 132620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 132820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1329c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1330bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1331bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1332bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 133334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 133520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 133620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 133720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 133920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 134120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 134420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 13463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 13473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 13483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1349ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 13503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 1351f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1352f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1353f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1354f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 13553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1356ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1357ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 13583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 13593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 13603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 13613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 13623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1364c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 136920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1372bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1373bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1374bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1375bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 137720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 137820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 137920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 138048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1382371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 138420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 138520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 138620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 138720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 138820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 139034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 139320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 139420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1395b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 139648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 139881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 139981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 140081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1401f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1402f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1403f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 140448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 140548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 140648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 140748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 141081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 141120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 141220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1414c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 141620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 141820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 141920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1422bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1423bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1424bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1425bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1430ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1432e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1433e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 14353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 14363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 14387be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 14397be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 144720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 144820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1451b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 145220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1455ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1456a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1457a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1458a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1459a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1460a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1461a6256238d9015c42129fe43791968768fe501efaJames Dong 1462134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1463134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1465f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1466f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1467f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1468ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1469ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1470ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1471ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 147220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 147320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 147420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1475c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 148120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 148220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1483bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1484bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1485bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1486bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 148720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 148820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 148920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 149020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 149120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 149220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1493274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1494274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1495274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 149720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 149820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15000517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15010517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 150220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 150720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 150820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 150920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 151020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1511274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1512274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1513274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 151620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 152020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 152120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 152220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 152620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1530274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1531274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1532274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 153520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 153620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 153920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 154020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 154120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 154220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1543738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 154449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 154549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 154649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 154749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 154849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1549738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 155005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 155105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 155205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 155305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 155405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 1555beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (max_size > SIZE_MAX - 10 * 2) { 1556beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("max sample size too big: %zu", max_size); 1557beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1558beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 155905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 156005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 156105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 1562beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen uint32_t width, height; 1563beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) || 1564beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) { 156505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1566f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1567f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 1568beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } else { 1569beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // A resolution was specified, check that it's not too big. The values below 1570beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // were chosen so that the calculations below don't cause overflows, they're 1571beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // not indicating that resolutions up to 32kx32k are actually supported. 1572beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (width > 32768 || height > 32768) { 1573beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("can't support %u x %u video", width, height); 1574beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1575beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 157605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1577f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 15784256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 15794256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 158007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) 158107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 158207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar // AVC & HEVC requires compression ratio of at least 2, and uses 1583f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1584f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1585f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1586f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1587f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1588f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 158905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1590f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 159105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1592113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 15934256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 15944256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1595113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1596113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1597113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1598113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1599113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1600949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (nSamples == 0) { 1601949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t trackId; 1602949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 1603949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 1604949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen Trex *t = &mTrex.editItemAt(i); 1605949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (t->track_ID == (uint32_t) trackId) { 1606949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (t->default_sample_duration > 0) { 1607949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t frameRate = 1608949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->timescale / t->default_sample_duration; 1609949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1610949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1611949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen break; 1612949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1613949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1614949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1615949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } else { 1616949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int64_t durationUs; 1617949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1618949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (durationUs > 0) { 1619949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t frameRate = (nSamples * 1000000LL + 1620949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen (durationUs >> 1)) / durationUs; 1621949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1622949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1623113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1624113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1625113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1626113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 162720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 162820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 162920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 163120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1632274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1633274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1634274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16350517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16360517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 163720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 163820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 163920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 164020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 164220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 164320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 164420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 164620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 16494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 1650274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1651274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1652274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 16554931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 16564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 16574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 16584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 16594931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 16604931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 16614931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 16624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 16634931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 16644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 16654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 166620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 166720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1668274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1669274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1670274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16710517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16720517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 167420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 167520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 167620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 167820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 167920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 168020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 168120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 168220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 168320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1684afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // \xA9xyz 1685e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh case FOURCC(0xA9, 'x', 'y', 'z'): 16864948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 16870517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16880517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1689afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // Best case the total data length inside "\xA9xyz" box 1690afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/", 16914948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 16924948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 16934948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 16944948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 16954948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16964948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16974948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16984948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 16994948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 17004948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 17014948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 17024948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17034948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 17044948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 17054948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 17064948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 17074948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 17084948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17094948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17104948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 17114948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 17124948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 17134948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17144948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17154948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 17164948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 17174948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 17184948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17194948818cb91176df74c972ac27b2f392b5d148bcJames Dong 172020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 17220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17230517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1729c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 173420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 173520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 173620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 173920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 174020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 174120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 174220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1743f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1744f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1745f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 174620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 174720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 174820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1749ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1750ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1751ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1752ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1753ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1754ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1755ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1756ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1757ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1758ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1759ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1760ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1761ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1762ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1763ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (mPath.size() >= 2 1764ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) { 1765ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar // Check if the video is MPEG2 1766ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar ESDS esds(&buffer[4], chunk_data_size - 4); 1767ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar 1768ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar uint8_t objectTypeIndication; 1769ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) { 1770ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) { 1771ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); 1772ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1773ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1774ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 177520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 177620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 177720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar case FOURCC('b', 't', 'r', 't'): 177946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar { 178046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar *offset += chunk_size; 178146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 178246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint8_t buffer[12]; 178346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (chunk_data_size != sizeof(buffer)) { 178446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return ERROR_MALFORMED; 178546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 178646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 178746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (mDataSource->readAt( 178846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar data_offset, buffer, chunk_data_size) < chunk_data_size) { 178946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return ERROR_IO; 179046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 179146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 179246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint32_t maxBitrate = U32_AT(&buffer[4]); 179346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint32_t avgBitrate = U32_AT(&buffer[8]); 179446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (maxBitrate > 0 && maxBitrate < INT32_MAX) { 179546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); 179646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 179746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (avgBitrate > 0 && avgBitrate < INT32_MAX) { 179846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate); 179946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 180046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar break; 180146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 180246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 180320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 180420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 18050517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18060517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1807d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 180820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18096a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 18106a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 18116a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 18126a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 18136a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen 181434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1815d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 181620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 181720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1819f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1820f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1821f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 182220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1823d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 182420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 182520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 182620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 18283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 18293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 18303b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 18316a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 18326a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 18336a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 18346a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 18356a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen 18363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 18373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 18383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 18393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 18403b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 1841f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1842f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1843f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 18443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 18453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 18463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 18473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 18483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 18493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 185020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1851244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1852244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 18530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 185417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 185517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 185617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 185717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 185817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 185917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 186017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 186117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 186217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 186317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 186417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 186517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 186617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 186717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1868ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size); 1869244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1870244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1871244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1872244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1873244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1874244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1875244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1876244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1877f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1878f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1879f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1880244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1881244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1882244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1883244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1884244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 188572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 188672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 18878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stop_offset = *offset + chunk_size; 18888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset = data_offset; 18898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang bool isParsingMetaKeys = underQTMetaPath(mPath, 2); 18908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!isParsingMetaKeys) { 18918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint8_t buffer[4]; 18928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (chunk_data_size < (off64_t)sizeof(buffer)) { 18938ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 18948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 18958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 1896bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 18978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 18988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang data_offset, buffer, 4) < 4) { 18998ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 19008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_IO; 19018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 190272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 19038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (U32_AT(buffer) != 0) { 19048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // Should be version 0, flags 0. 1905ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 19068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // If it's not, let's assume this is one of those 19078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // apparently malformed chunks that don't have flags 19088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // and completely different semantics than what's 19098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // in the MPEG4 specs and skip it. 19108ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 19118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 19128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 19138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += sizeof(buffer); 191472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 191572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 191672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 191772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 191872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 191972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 192072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 192172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1922bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1923bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1924bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1925bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 192672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 192772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 192872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 19295d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 19305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 193172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 193272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 19330517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19340517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 193572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1936fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 193772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 193872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 193972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 194072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 194172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 194272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 194372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 194472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 194572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 194672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 194772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 19480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19490517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1950c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 195172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 195272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 195372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1954c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 195572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 195672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 195772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 195872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 195972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 196072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1961fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 1962c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 196372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 196472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1965fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1966c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 1967c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1968c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1969c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1970bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1971bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 197272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 197372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1974fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 1975c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 1976c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1977c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1978c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1979c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1980c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 19813724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) { 1982c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 198372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 198472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 198572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 19863724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (convertTimeToDate(creationTime, &s)) { 19873724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen mFileMetaData->setCString(kKeyDate, s.string()); 19883724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 198972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 199072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 199172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 199272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 199372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1994c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 1995c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1996c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1997c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1998c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 1999c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2000c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2001c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2002c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 2003c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 2004c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 2005c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 2006c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2007c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2008c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2009c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 2010c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 2011c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 2012c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 2013c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2014c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2015c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 2016c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 2017c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 2018c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2019c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 2020c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 2021c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 2022c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 2023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 2024c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 2025c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2026c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 2027c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 2028c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2029c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2030c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2031e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 2032c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 2033c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2034c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2035c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2036c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2037c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2038dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 2039dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 2040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 2041928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 2042928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound = true; 2043928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 2044dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 2045dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 2046dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 2047dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2048dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2049dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 2050dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 2051dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2052dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2053dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 2054dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2055dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 20563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 20573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 20580517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2060ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang if (underQTMetaPath(mPath, 3)) { 2061ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang break; 2062ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang } 2063ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang 20643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 20653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 20663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 20673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 20683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 20713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 2072e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 2073e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 2074e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 2075cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar if (mLastTrack != NULL) { 2076cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 2077cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar } 20783b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20793b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 20813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang case FOURCC('k', 'e', 'y', 's'): 20848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang { 20858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 20868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 20878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 20888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaKey(data_offset, chunk_data_size); 20898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 20908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang break; 20918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 20928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 2093c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 2094c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 2095c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 2096c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2097c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 2098c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2099c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2100c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 2101c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 2102c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 2103c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 2104c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 2105c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 2106c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2107c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2108c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 2109c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2110c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2111c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 21127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 21137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 2114f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2115f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2116f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 21173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 21183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 21193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 21203b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 21213b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 21223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 21233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21250e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) { 2126dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake return ERROR_MALFORMED; 2127dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake } 2128dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake 21298da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 21308da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 21318da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 21328da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 21333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 21353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 21363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 21393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 21403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 21413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 21423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21430517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 21440517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 21463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 21493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 21503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 21527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 21537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 21547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 21557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 21567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 2157515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 2158515e855eae78aa495da58356486aaa666cb57fd1James Dong { 21590517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2161515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 2162635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, 2163635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert chunk_data_size, data_offset); 21641e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake 2165635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) { 21661e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake return ERROR_MALFORMED; 21671e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake } 21681552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 21696a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 21706a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 21716a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 21726a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 2173515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 21741552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 2175515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 2176515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2177515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 217897d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake if (chunk_data_size <= kSkipBytesOfDataBox) { 217997d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake return ERROR_MALFORMED; 218097d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake } 218197d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake 2182515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 2183515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 21841552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 2185515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2186515e855eae78aa495da58356486aaa666cb57fd1James Dong 2187515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 2188515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2189515e855eae78aa495da58356486aaa666cb57fd1James Dong 219058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar case FOURCC('c', 'o', 'l', 'r'): 219158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar { 219258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar *offset += chunk_size; 219358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd') 219458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // ignore otherwise 219558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) { 219658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar status_t err = parseColorInfo(data_offset, chunk_data_size); 219758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (err != OK) { 219858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return err; 219958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 220058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 220158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 220258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar break; 220358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 220458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2205fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2206fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2207fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2208fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2209fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2210fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2211fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 22120517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 22130517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2214fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 2215fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2216fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 2217fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 2218fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2219fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2220fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2221fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2222fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2223328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 2224328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 22250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 22260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2227328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 2228328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 2229328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2230328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2231328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 2232328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2233328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 2234328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2235328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 22365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 22375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 22385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 22395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 22405d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 22415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 22425d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 22435d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 22445d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 224505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 224605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 224705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 224805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 224905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 225005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 225105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 225220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 225320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 22548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // check if we're parsing 'ilst' for meta keys 22558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // if so, treat type as a number (key-id). 22568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 22578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaVal(chunk_type, data_offset, chunk_data_size); 22588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 226020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 226120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 226220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 226320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 226420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 226520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 226620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 226720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 226805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 226905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 227005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 227105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 227205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 227305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 227405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 227505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 227605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 227705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 227805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 227905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 228005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 228105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 228205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 228305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 228405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 228505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 228605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 228705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 228805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 228905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 229005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 229105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 229205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 229305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 229405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 2295e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (timeScale == 0) 2296e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake return ERROR_MALFORMED; 229705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 229805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 229905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 230005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 230105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 230205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 230305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 230405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 230505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 230605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 230705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 230805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 230905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 231005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 231105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 231205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 231305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 231405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 231505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 231605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 231705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 231805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 231905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 232005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 232105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 232205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 232305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 232405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 232505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 232605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 232705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 232805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 232905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 233005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 233105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2332a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 233305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 233405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 233505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 233605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 233705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 233805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 233905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 234005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 234105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 234205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 234305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 234405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 234505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 234605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 234705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 234805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 234905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 235005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 235105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 235205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 235305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 235405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 235505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 235605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 235705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 235805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 235905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 236005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 236105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 236205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 236305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 23643f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 23653f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 23663f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 23673f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 236805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 236905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 237005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 237105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 237205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 237305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 237405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 237505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 237605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 237705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2378c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 237905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2380f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2381f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2382f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 238305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 238405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2385c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 238605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 238705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 238805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 238905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 23908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) { 23918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size < 8) { 23928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t count; 23968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &count)) { 23978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mMetaKeyMap.size() > 0) { 24018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGW("'keys' atom seen again, discarding existing entries"); 24028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.clear(); 24038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t keyOffset = offset + 8; 24068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stopOffset = offset + size; 24078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang for (size_t i = 1; i <= count; i++) { 24088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyOffset + 8 > stopOffset) { 24098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t keySize; 24138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset, &keySize) 24148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keySize < 8 24158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keyOffset + keySize > stopOffset) { 24168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24178cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24188cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24198cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t type; 24208cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset + 4, &type) 24218cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || type != FOURCC('m', 'd', 't', 'a')) { 24228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keySize -= 8; 24268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += 8; 24278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang sp<ABuffer> keyData = new ABuffer(keySize); 24298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyData->data() == NULL) { 24308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 24338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset, keyData->data(), keySize) < (ssize_t) keySize) { 24348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang AString key((const char *)keyData->data(), keySize); 24388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.add(i, key); 24398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += keySize; 24418cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 24438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 24448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal( 24468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang int32_t keyId, off64_t offset, size_t size) { 24478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ssize_t index = mMetaKeyMap.indexOfKey(keyId); 24488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (index < 0) { 24498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // corresponding key is not present, ignore 24508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 245205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 24538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size <= 16) { 24548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataSize; 24578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &dataSize) 24588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || dataSize > size || dataSize <= 16) { 24598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t atomFourCC; 24628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &atomFourCC) 24638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || atomFourCC != FOURCC('d', 'a', 't', 'a')) { 24648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataType; 24678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 8, &dataType) 24688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || ((dataType & 0xff000000) != 0)) { 24698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // not well-known type 24708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang dataSize -= 16; 24748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang offset += 16; 24758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (dataType == 23 && dataSize >= 4) { 24778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // BE Float32 24788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t val; 24798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &val)) { 24808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) { 24838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val); 24848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } else { 24868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // add more keys if needed 24878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGV("ignoring key: type %d, size %d", dataType, dataSize); 24888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 24918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 249205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2493ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2494c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2495ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2496ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2497ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2498ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2499ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2500ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2501ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2502ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2503ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2504ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2505ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2506ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2507ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2508c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2509ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2510ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2511ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2512ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2513ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2514ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2515ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2516ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2517b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint64_t ctime __unused, mtime __unused, duration __unused; 2518ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2519ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2520ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2521ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2522ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2523ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2524ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 252504022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2526ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2527ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2528ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2529ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 253004022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 253104022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2532ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2533ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2534f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2535f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2536f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2537ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2538ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2539ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2540ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2541ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2542ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2543ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2544ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2545ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2546b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2547b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2548b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 2549df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2550ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2551df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2552ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2553ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2554ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2555ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2556ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2557ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2558ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2559ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2560ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2561ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2562ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2563ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2564ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2565ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2566ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2567ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 25685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2569ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2570ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2571ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2572ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2573ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2574ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2575ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2576b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2577b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2578ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2579ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2580b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2581b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2582ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2583ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2584ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2585ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2586fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 2587c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich if (size < 4 || size == SIZE_MAX) { 258872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 258972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 259072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 25918da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 25928da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 25938da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 25948da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 259572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 259672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 259772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 259872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 259972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 260072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 260172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 260272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 260372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 260472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 260572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 26065d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 26075d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 2608ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("meta: %s @ %lld", chunk, (long long)offset); 26092d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer switch ((int32_t)mPath[4]) { 261072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 261172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 261272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 261372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 261472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 261572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 261672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 261772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 261872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 261972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 262066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 262166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 262266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 262366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 262466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 262572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 262672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 262772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 262872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 262972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 263072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 263172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 263272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 263372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 263472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 263572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 263672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 263772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 263872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 263972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 264072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 264172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 264272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 264372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 264472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 264572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 264672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 264772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 264872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 264972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 265026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 265126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 265226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 265326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 265426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 265511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 265611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 265711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 265811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 265911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 266011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 266111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 266211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 266311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 266411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 266511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 266672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 266772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 266872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 266972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2670afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2671afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2672afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 267372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 267472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 267572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 267672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 267772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 267826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 267926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2680afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 268126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2682afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2683afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2684afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 268526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 268626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 268726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 268826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 268926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 26905d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 26915d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 26925d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 26935d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 26945d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 26955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 26965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 26975d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 26985d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 26995d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 27005d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 27015cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia if (size < 8) { 27025cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia delete[] buffer; 27035cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia buffer = NULL; 27045cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia ALOGE("b/24346430"); 27055cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia return ERROR_MALFORMED; 27065cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia } 27075d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 27085d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 27095d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 27108c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 27118c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 27128c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 27138c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 27148c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 27158c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 27168c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 27178c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 27188c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 27198c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 27208c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 27218c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 27228c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 27238c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 27248c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 2725f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2726f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2727f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 27288c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 27298c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 27308c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 27315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 27328c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 27335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 27345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 27355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 27365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 27375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 27385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 273926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 274072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 274172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 274272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 274372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2744328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 274572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 274672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 274772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 274872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 274972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 275072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 275126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 275226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 275326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 275426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 275526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 275626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 275726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 275826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 275926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 276072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 276126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 276272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 276372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 276426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 276526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 276626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 276726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 276826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 276926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 277072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 277172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 277272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 277372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 277472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 277572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 277672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 277772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 277872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 277972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 278072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 278172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 278272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 278372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 278472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 278558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { 278658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) { 278758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 278858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 278958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 279058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 279158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (buffer == NULL) { 279258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 279358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 279458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) { 279558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 279658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 279758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 279858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_IO; 279958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 280058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 280158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t type = U32_AT(&buffer[0]); 280258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11) 280358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) { 280458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t primaries = U16_AT(&buffer[4]); 280558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t transfer = U16_AT(&buffer[6]); 280658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t coeffs = U16_AT(&buffer[8]); 280758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128); 280858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 280958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorAspects aspects; 281058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorUtils::convertIsoColorAspectsToCodecAspects( 281158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar primaries, transfer, coeffs, fullRange, aspects); 281258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 281358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // only store the first color specification 281458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { 281558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); 281658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); 281758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); 281858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); 281958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 282058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 282158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 282258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 282358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 282458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 282558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return OK; 282658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar} 282758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2828fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 28295cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake if (size < 4 || size == SIZE_MAX) { 2830fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2831fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2832fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 28335cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 28348da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 28358da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 28368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 2837fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2838fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2839fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2840fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2841fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2842fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2843fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2844fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2845fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2846fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2847fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2848fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2849fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2850fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2851fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2852fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2853fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2854fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2855fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2856fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2857fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2858fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2859fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2860fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2861fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2862fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2863fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2864fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2865fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2866fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2867fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2868fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2869fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2870fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2871fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2872fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2873fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2874fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2875fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2876fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2877fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2878fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2879fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2880fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2881fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2882fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2883fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2884fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2885fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2886fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2887fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2888fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2889fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2890fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2891fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2892fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2893fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2894fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2895fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2896fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2897fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2898fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2899fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2900fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2901fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 29029458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake if (size < 6) { 29039458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake return ERROR_MALFORMED; 29049458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake } 29059458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake 2906fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2907fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2908fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2909fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2910fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2911fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2912fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2913fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2914fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2915fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2916fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2917fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2918fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2919fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2920fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2921fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2922fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2923fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2924fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2925fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2926fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2927fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2928fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 29295cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake buffer[size] = 0; 2930fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2931fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2932fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2933fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2934fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2935fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2936fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2937fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2938fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2939fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2940fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2941fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2942fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2943fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2944328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2945328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2946328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2947328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2948328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2949328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2950328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2951328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2952328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2953328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2954328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2955328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2956328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2957328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2958328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2959328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2960328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2961328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2962328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2963328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2964328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2965328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2966328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2967328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2968328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2969328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2970328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2971328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2972328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2973328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2974328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2975328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2976328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2977328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2978328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2979328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2980328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2981328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2982328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2983328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2984328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2985328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2986328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2987328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2988328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2989328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2990328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2991328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2992328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2993328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2994328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2995328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2996328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2997328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2998328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2999328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3000b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) { 300120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 300220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 3003693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 300420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 300520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 300620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 300720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 300820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 3009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 301020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 301120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 301220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 301320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 301420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 301520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3016371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 3017371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 3018371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 3019371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3020c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3021c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 3022c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 3023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 3024c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 3025949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen Trex *t = &mTrex.editItemAt(i); 3026c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 3027c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 3028c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 3029c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 3030c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 30310386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } else { 30320386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia ALOGE("b/21657957"); 30330386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia return NULL; 3034c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 3035c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3036a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 3037ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3038a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const char *mime; 3039a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findCString(kKeyMIMEType, &mime)) { 3040a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3041a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3042a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3043a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 3044a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 3045a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 3046a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 3047a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) { 3048a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3049a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3050a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3051a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 3052a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3053a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 3054a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3055a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3056a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 3057a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 3058a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 3059a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 3060a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) { 3061a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3062a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3063a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3064a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 3065a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3066a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 22 || ptr[0] != 1) { // configurationVersion == 1 3067a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3068a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3069a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3070a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3071942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen return new MPEG4Source(this, 307205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 3073c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 307420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 307520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3076bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 3077bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 3078bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 3079bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3080bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3081bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 3082bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 3083bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 3084bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 3085bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 3086bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 3087bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 3088bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 30893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 30903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 30913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 30923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 30933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3094bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 3095ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) 3096bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 3097bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 3098bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 3099bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 3100bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 3101bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 3102bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3103ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 3104169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 3105ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 3106169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 3107169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 3108169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 31092e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (track->timescale == 0) { 31102e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale invalid."); 31112e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 31122e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 31132e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 3114bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 3115bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 3116bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3117f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 3118f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 3119f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 3120f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 3121f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 3122f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 3123f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 3124f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 3125f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 3126f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 3127f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 3128f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 3129f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 3130f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 3131f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 3132f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 3133f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 3134f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 3135f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 3136f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 3137f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 3138f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 3139f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 3140f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 3141f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 3142f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 3143f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 3144f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 3145f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 3146f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 3147f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 3148f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 3149f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 3150f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3151f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 3152f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3153f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 3154f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 3155f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 3156f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 3157f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 3158f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 3159f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 3160f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 3161f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3162f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 3163f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 3164f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 3165f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3166f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 3167f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 3168f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3169ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 3170ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 3171ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 317281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 317381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 317481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 317581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 317681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 317781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 317881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 317981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 3180f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3181f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3182f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 318381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 318481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 318581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 318681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 3187633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 3188633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 3189633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 3190633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 319129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 3192633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 3193633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 3194633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 3195ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 3196ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 3197ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 3198ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 3199ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3200ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3201ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3202b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 3203ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar printf("ESD of size %zu\n", csd_size); 3204b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(csd, csd_size); 3205b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 3206ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3207a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 3208a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 3209a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 3210a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 3211a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3212a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 3213a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 3214a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3215ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 3216ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3217ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3218ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 321900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 322000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 322100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 322200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 322300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 3224aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 3225aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 3226ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3227aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 3228aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 3229ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3230ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3231f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3232f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3233f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3234db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 3235db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 3236db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 3237aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 3238aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 3239ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 3240ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 3241ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 32428e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 28) return ERROR_MALFORMED; 3243aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 3244aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 3245ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 32468e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3247595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 324800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 324900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 325000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 3251ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3252ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 325300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 325400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 3255595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 3256f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 32578e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 325800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 3259b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t extSampleRate __unused; 326000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 326100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 3262595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 3263595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 32648e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 24) return ERROR_MALFORMED; 326500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 326600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 326700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 326800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 326900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 327000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 3271595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 327200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 327300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 3274ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3275ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3276f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 3277f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 3278f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 3279f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 3280f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 3281f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 3282f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 3283f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 3284f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 3285f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 3286f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3287f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 3288f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 3289f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3290f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 3291f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 3292f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 3293f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 3294f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3295f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 3296f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 3297f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3298f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3299f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 3300f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 33018e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3302f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 3303f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3304f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 33058e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 6) return ERROR_MALFORMED; 3306f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 3307f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3308f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3309f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 3310f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 3311f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 33128e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 2) return ERROR_MALFORMED; 3313b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t frameLengthFlag __unused = br.getBits(1); 3314f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3315f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 3316f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3317f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 33188e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 14) return ERROR_MALFORMED; 3319b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t coreCoderDelay __unused = br.getBits(14); 3320f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3321f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 332245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 332345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 332445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 332545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 332645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 332745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 332845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 332945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 333045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 333145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 333245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 333345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 333445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 333545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 333645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 333745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 33388e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 333945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 334045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 334145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 334245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 334345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 3344f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 334545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 3346f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 3347f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 33488e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 32) { 33498e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 33508e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen } 3351b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t ElementInstanceTag __unused = br.getBits(4); 3352b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t Profile __unused = br.getBits(2); 3353b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SamplingFrequencyIndex __unused = br.getBits(4); 3354f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 3355f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 3356f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 3357f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 3358b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumAssocDataElements __unused = br.getBits(3); 3359b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumValidCcElements __unused = br.getBits(4); 3360f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3361f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 33628e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen 3363f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 33648e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3365b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MonoMixdownElementNumber __unused = br.getBits(4); 3366f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3367f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 33688e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3369f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 3370f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 33718e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3372b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t StereoMixdownElementNumber __unused = br.getBits(4); 3373f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3374f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 33758e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3376f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 3377f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 33788e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 3) return ERROR_MALFORMED; 3379b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MatrixMixdownIndex __unused = br.getBits(2); 3380b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t PseudoSurroundEnable __unused = br.getBits(1); 3381f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3382f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3383f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 3384f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 33858e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3386f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 3387b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t FrontElementTagSelect __unused = br.getBits(4); 3388f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 3389f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3390f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3391f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 33928e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3393f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 3394b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SideElementTagSelect __unused = br.getBits(4); 3395f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 3396f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3397f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3398f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 33998e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3400f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 3401b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t BackElementTagSelect __unused = br.getBits(4); 3402f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 3403f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3404f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 3405f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3406f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 34078e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3408b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t LfeElementTagSelect __unused = br.getBits(4); 3409f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 3410f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3411f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 3412f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 3413f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 3414f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3415f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3416f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3417f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3418ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 3419ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 3420ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3421ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3422f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3423f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3424f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3425ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 3426ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 3427ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3428ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 34293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 3430ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 3431ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3432ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3433ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 3434ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3435ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 3436ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 3437ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3438ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 34393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 3440ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 3441ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3442ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3443ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 3444ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3445ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 3446ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 3447ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 344820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 344920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 345020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 3451942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 345220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 3453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 345448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 345505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 345605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 3457c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 345805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 3459942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 3460942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 346120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 346248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 346320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 346420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 346505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 346605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 3467c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 346805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 346905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 347005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 3471ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 3472ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 3473ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 3474ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 347520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 34763b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 34776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 347820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 347920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 348020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 3481dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 34820024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 3483ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3484c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 3485c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3486ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 348748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 3488ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 3489ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 3490ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 3491ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 3492ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 3493ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 3494ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 3495ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 3496ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3497ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 349820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 349920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 3500dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 350120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 350218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 35033b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 35046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 35066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 35076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 35086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 35096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 35106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 35126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3514ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 35156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 35176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 35183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 35193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 35203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 35213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 35223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 35233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 35243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 35253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3526a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia CHECK(size >= 22); 35273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 35283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 35293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 35306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 353105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 353305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 353405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 353505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 353605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 353705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 353820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 353920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 354020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 354120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 354220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 354320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3544ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3545ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 354620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 354720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 354820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 35497b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 35507b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3551dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 355220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 355320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3554dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 355520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3556dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 355720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3558dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 355920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 356020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3561afd492436efc7f66b958da14659b52232efa5910Marco Nelissen int32_t tmp; 3562afd492436efc7f66b958da14659b52232efa5910Marco Nelissen CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp)); 3563afd492436efc7f66b958da14659b52232efa5910Marco Nelissen size_t max_size = tmp; 356420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3565afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // A somewhat arbitrary limit that should be sufficient for 8k video frames 3566afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // If you see the message below for a valid input stream: increase the limit 3567afd492436efc7f66b958da14659b52232efa5910Marco Nelissen if (max_size > 64 * 1024 * 1024) { 3568afd492436efc7f66b958da14659b52232efa5910Marco Nelissen ALOGE("bogus max input size: %zu", max_size); 3569afd492436efc7f66b958da14659b52232efa5910Marco Nelissen return ERROR_MALFORMED; 3570afd492436efc7f66b958da14659b52232efa5910Marco Nelissen } 3571afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = new MediaBufferGroup; 3572738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 35730024245e134467d120b40099da16c467dc365e76Andreas Huber 35748da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 35758da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 35768da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 3577afd492436efc7f66b958da14659b52232efa5910Marco Nelissen delete mGroup; 3578afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = NULL; 35798da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 35808da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 358120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 358220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 358320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 358420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 358520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 358620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 358720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 35887b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 35897b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3590dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 359120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 359220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 359320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 359420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 359520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 359620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35970024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 35980024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 35990024245e134467d120b40099da16c467dc365e76Andreas Huber 360020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 360120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 360220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 360320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 360420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 360520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 360620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 360720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 360820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 360905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 361005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 361105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 361205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 361305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 363005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 363105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 3636ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset); 363705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 363905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 364105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 364205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 364305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 364405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 364505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 364605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 364705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 364805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 364905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 365005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 36533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 36543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 36553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 36563f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 36573f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 36583f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 36593f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 36603f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 36613f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 36623f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 36633f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 36643f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 36653f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 36663f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 367205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 367305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 367405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 367505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 368105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 368205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 368305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 368405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 368505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 368805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 368905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 369005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 369105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3692ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3693ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3694ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3695ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3696ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3697ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3698ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3699ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3700ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3701ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3702ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3703ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3704ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3705ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3706ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3707ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3708ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3709ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 3710ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 3711ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 3712ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 3713ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3714ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3715ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3716ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 371705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 371805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 371905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 372005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 372105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 372205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 372305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 372405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 372584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 372684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3727ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3728ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3729ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3730ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3731ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3732ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3736ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3737ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3738ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3739ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3740ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3741ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3742ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3743ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3745ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3746ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3748ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3752ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3753ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3754ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3755ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3756ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3757ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3758ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3759ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3760ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3761ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3762ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3763ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3764ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3765ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3766ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3767ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3768ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3769ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3770ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3771ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 377248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3773ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3774ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 377548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 377648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 377748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 377848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3779ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3780ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3781ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3782ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3783ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3784ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3785ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3786ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3787ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 378884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 378984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3790ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3791ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3792ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3793ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3794ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3795ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3796ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3797ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3798ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3799ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3800ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3801ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3802ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3803ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3804ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3805ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3806ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3807ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3808ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3809c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount == 0) { 3810c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 3811c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3812c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount > UINT32_MAX / 8) { 3813c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return ERROR_MALFORMED; 3814c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3815ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3816ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3817c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3818c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (newPtr == NULL) { 3819c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return NO_MEMORY; 3820c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3821c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia mCurrentSampleInfoOffsets = newPtr; 3822ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3823ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3824ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3825ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3826c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (mCurrentSampleInfoOffsets == NULL) { 3827c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 3828c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3829c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia 3830ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3831ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3832ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3833ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3834ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3835ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3836ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3837ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3838ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3839ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3840ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3841ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3842ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3843ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3844ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3845ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3846ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3847ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3848ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3849ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3850ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3851ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3852ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3853ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3854ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 385548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 3856529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen // only 0, 8 and 16 byte initialization vectors are supported 3857529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (ivlength != 0 && ivlength != 8 && ivlength != 16) { 3858529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("unsupported IV length: %d", ivlength); 3859529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen return ERROR_MALFORMED; 3860529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 386148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3862ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3863529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (i >= mCurrentSamples.size()) { 3864529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("too few samples"); 3865529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen break; 3866529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 3867ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3868ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3869ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3870ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3871ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3872ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3873ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3874ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3875ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 387648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 387748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 387848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3879ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 388048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 388148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 388248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3883ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3884ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3885ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 388648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 388748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 388848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 388948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 389048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 389148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 389248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 389348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 389448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 389548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 389648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 389748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 389848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3899ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 390048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 390148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 390248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3903ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3904ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3905ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3906ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3907ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3908ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3909ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3917ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 392605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 392705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 393005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 393105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 393205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 393305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 393505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 393605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 393705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 393805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 394005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 394205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 394705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 394805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 394905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 395005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 395105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 395405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 395505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 395605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 395905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 396005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 398605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 398705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 399005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 399105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 399205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 399505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 399605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 399805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 399905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 400005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 400205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 400305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 400405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 400605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 400705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 400805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 401005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 401105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 401205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 401305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 401405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 401505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 401905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 402005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 402105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 402205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 402305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 402405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 402605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 402705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 402805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 402905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 403005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 403205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 403305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 403605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 403705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 403805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 404105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 404205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 404305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 404505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 404605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 404805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 405005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 405105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 405205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 405305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 405405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 405505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 405605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 405705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 405805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 405905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 406205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 406405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 406505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 406805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 406905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 407005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 407105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 407205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 407305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 407405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 407505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 407605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 407705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 407805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 407905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 408005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 408105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 408205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 408305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 408405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 408505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 408605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 408705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 4088c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 4089c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 409005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 409105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 409205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 409305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 409405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 409505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 409605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 409705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 409805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 409905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 410005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 410205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 410305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 410405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 410505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 410605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 410705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 410805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 410905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 411005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 411105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 411205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 411305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 411405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4116ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar if (size < (off64_t)(sampleCount * bytesPerSample)) { 411705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 411805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 412005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 412105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 412205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 412305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 412405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 412505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 412605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 412705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 412805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 412905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 413005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 413105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 413205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 413305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 413405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 413505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 413605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 413705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 413805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 413905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 414005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 414105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 414205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 414305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 414405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 414505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 414605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 414705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 414805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 414905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4150a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 4151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 415205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 415305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 415405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 415505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 415605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 415705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 4158c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 415905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 416005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 416205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 416305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 416505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 416705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 416805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 416920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 41707b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 41717b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 417220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 417320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 417420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 41766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 41776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 41786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 41796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 41806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 41816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 41826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 41836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 41846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 41856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 41866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 41876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 41886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 41896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 41906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 41916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 41926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 41936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 419420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 419520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 41967b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 41977b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 4198dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 419920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 420005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 420105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 420205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 420305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 420420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 420520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4206abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 4207abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 420820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 4209abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 4210abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 4211abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 4212abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 4213abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 4214abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4215abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4216abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 4217abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 4218abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4219abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 4220abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 4221abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 4222abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4223abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 4224abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 4225abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4226abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4227abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 422820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 4229abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 4230599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 4231abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 4232abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4233abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4234abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 4235abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 4236abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 4237abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4238abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4239abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4240abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 4241abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 4242abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 4243abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 4244abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 424520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4246788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 4247788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 4248788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 4249788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 4250788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 4251788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 425220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 42535295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 42545295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 42555295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 42565295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 42575295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 42585295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 42595295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 42605295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 426105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 426220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 426320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 426420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4265abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4266abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 4267abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4268abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4269abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 4270abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 4271abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 4272abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 4273abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4274df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 4275abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 4276abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 4277abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 4278abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 4279abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 4280abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4281abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 428220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 428320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 428420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 428520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 428620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 428720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 428820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 428920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4290c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 42910024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 4292170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 42938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 4294dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 4295dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 4296dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 429720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4298c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 4299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 4300170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 430120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4302dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4303dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4304dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4305dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4306dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 4307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 4308dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4309ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 4310dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4311dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4312c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4313c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4314c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4315c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 43160024245e134467d120b40099da16c467dc365e76Andreas Huber } 431720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 4319dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 4320dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 432134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 4322dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4323dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 4324dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4325dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4326dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4327dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 4328dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4329dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43307b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4331dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 4332dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 433348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 43344678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4335170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4336170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4337abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4338abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4339abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4340abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4341abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4342abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 43438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 43448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 43458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 43468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4347dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 4348dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4349dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 4351dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 4352dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4353dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4354dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4355dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4356dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4357dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 4358dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 4359dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 4361dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4362dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 4363dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 4364dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 43665d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 43675d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 43685d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 43695d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 437029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 4371e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4372e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 4373e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 4374e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4375e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 4376e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 4377dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4378dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 43797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 43806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 4381dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43827b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4383dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 43846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 43856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 4386dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4387dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 4388dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4389dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4390dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4391dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4392dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 4393dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4394dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4395dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 4396dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 4397dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 4398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 4399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 4400dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 4403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 4404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 4406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 440720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 440820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 440920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 441020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 441120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4412dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 441320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 441420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4415dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4416dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4417dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 44186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 4419dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4420dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 4421dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 4422dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 4423e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 4425bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 442634fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 442734fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 442834fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 442934fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 4430bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength); 443134fe252c89e33572d01fea981b58d7b115e76164James Dong } 4432e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 443334fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 443429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 4435dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 4436dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 4437dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 4438dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4439dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 4440dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 4441dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 4442dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4443dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 444487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 444587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 444687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 444787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size()); 444887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen android_errorWriteLog(0x534e4554, "27208621"); 444987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer->release(); 445087afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer = NULL; 445187afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen return ERROR_MALFORMED; 445287afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen } 4453dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4454dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4455dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4456dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4457dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 4458dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 4459dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 4460dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 4461dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4462dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 4463dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4464dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 4465dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4466dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 446720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 446848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 44694678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4470170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4471170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4472abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4473abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4474abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4475abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4476abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 44788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 44798bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 44808bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 44818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 448220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 448320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 448420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 448520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 448620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 448720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 448820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 448920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 449020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 449105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 449205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 449305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 449405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 449505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 449605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 449705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 449805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 449905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 450005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 450105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 450205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 450305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 450405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 450505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 450605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 450705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 450805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 450905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 451005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 451105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 451205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 451305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 45143f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 451505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 451605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 451705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 451805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 451905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 452005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 452105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 452205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 452305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 452405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 452505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 452605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4527ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 4528ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4529ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4530ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 4531ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 4532ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 4533ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 4534ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 4535ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4536ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4537ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 4538ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 4539ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 454005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 454105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 454205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 454305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 454405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 454505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 454605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 454705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 454805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 454905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 455005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4551442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 455205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 455305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 455405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 455505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 455605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 455705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 455805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 45593f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 45603f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 45613f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 45623f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4563ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 456405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 456505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 456605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 456705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 4568ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4569ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4570ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 457105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 457205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 457305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 457405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 457505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4576c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 457705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 457805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 457905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 458005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 458105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 458205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 458305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 458405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 458505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 458605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4587c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4588c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4589c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4590c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 459105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 459205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 459348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 459448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 459548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 459648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 459748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 459848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 459948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 460048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 460148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 460248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 460348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 460448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 460548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 460648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 460748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 46083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 460905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 4610da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (!isInRange((size_t)0u, mBuffer->size(), size)) { 4611da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4612da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4613da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 4614da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size); 4615da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4616da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4617da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 461805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 461905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 462005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 462105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 462205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 462305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 462405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4625da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 462605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 462705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 462805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 462905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 463005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 463105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 463205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4633170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4634170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 463505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 463605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 463705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 463805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 463905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 464005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 464205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 464305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 464405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 464605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 464705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 46483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 464905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 465005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 465105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 465205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 465305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 465405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 465505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 465605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 465705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 465805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 465905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 466005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 466105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 466205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 466305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 46645d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 46655d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 46665d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 46675d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen 46685d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 466905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 467005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 467105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 467205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 467305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 467405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 467505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 467605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 467705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 467805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 467905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 468005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 468105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 468205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 468305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 468405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 468505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 468605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 468705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 468805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 468905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 469005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 469105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 469205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 469305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 469405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 469505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 469605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 469705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 469805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 469905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 470005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4701da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih void *data = NULL; 4702da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih bool isMalFormed = false; 470305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 4704da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) { 4705da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 4706da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 4707da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mBuffer->data(); 4708da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 470905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 4710da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih int32_t max_size; 4711da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mFormat == NULL 4712da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !mFormat->findInt32(kKeyMaxInputSize, &max_size) 4713da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, (size_t)max_size, size)) { 4714da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 4715da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 4716da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mSrcBuffer; 4717da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 471805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 471905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4720da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (isMalFormed || data == NULL) { 4721da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("isMalFormed size %zu", size); 4722da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer != NULL) { 4723da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4724da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4725da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4726da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4727da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4728da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih num_bytes_read = mDataSource->readAt(offset, data, size); 4729da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 473005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 473105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 473205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 473305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4734da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 473505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 473605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 473705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 473805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 473905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 474005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 474105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 474205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 474305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 474405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 474505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 474605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 474705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 4748da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 474905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 475005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 475105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 475205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 4753da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength) 4754da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u) 4755da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength); 475605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 475705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 475805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 4759da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("Video is malformed; nalLength %zu", nalLength); 476005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 476105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 476205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 476305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 476405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 476505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 476605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 476705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 476805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 47695403587a74aee2fb57076528c3927851531c8afbMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 47705403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 47715403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 47725403587a74aee2fb57076528c3927851531c8afbMarco Nelissen ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size()); 47735403587a74aee2fb57076528c3927851531c8afbMarco Nelissen android_errorWriteLog(0x534e4554, "26365349"); 47745403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer->release(); 47755403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer = NULL; 47765403587a74aee2fb57076528c3927851531c8afbMarco Nelissen return ERROR_MALFORMED; 47775403587a74aee2fb57076528c3927851531c8afbMarco Nelissen } 477805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 477905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 478005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 478105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 478205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 478305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 478405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 478505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 478605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 478705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 478805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 478905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 479005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 479105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 479205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 479305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4794170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4795170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 479605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 479705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 479805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 479905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 480005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 480105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 480205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 480305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 480405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 480505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 480605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 480705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 480805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 480905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 481005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 481105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 481205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 481305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 481405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4815bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4816bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 4817bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4818bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 4819bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4820bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4821bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4822bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4823bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4824bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4825bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4826bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4827bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4828bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 48291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4830693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 483120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 483220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 483334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 483420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 483520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 483620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 483720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 483820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4839b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4840b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 48410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4842ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4843983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 484418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 48455a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 484620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 484720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 484820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 484920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 485020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 485120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 485220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 48541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 48551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 48561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 48571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 48583b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 48593b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 48601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 48611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 48621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 48634cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 48644cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 48654cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 48664cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 48674cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 486858fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 486958fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 487058fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 48711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 48721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 48741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 48751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 48761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 48771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 48781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 48821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 48831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 48851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4886a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4887a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4888a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 48891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4890a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4891a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4892a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4893a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 48941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4895a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4896a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4897a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4898a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 48991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4900a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4901a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4902a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4903a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4904a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4905a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4906a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4907a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4908a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4909a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4910a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4911a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 49121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 49131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4915a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4916a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4917a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4918a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4919a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4920a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4921a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4922452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 4923a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4924a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4925a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4926a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4927a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4928452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - offset) is either 8 or 16 4929452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset); 4930452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunkDataSize < 0) { 4931452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 4932452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 4933452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 4934a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 493505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 493605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 4937ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset); 4938a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4939a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4940a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4941a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4942a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4943a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4944a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4945a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4946a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4947a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4948a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4949a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4950a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4951a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4952a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4953a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4954a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4955a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4956a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4957a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4958a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4959a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4960a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4961a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4962a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4963a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4964a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4965a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4966a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4967a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4968a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4969a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4970a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 49711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 49721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4973a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4974a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4975a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4976a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4977a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4978a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4979a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4980a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4981a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4982a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4983a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 49841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4985a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4986a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 49871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4989a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 49901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 49911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 49931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 49945a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 49951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4996a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4997a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4998a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4999a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5000ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset); 5001a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5002a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 50031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 50041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 50051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 50061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 50075a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 5008a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 5009a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 50101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 50111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 50121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 50131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 50145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 50151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 50161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 50171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 50181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 50191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 50201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 502120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 5022