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" 474dbff11975e737482537e1636051690188f3fbc4Praveen Chavan#include "include/avc_utils.h" 48fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 49937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#ifndef UINT32_MAX 50937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#define UINT32_MAX (4294967295U) 51937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#endif 52937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 550dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnarenum { 560dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar // max track header chunk to return 570dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar kMaxTrackHeaderSize = 32, 582fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen 592fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen // maximum size of an atom. Some atoms can be bigger according to the spec, 602fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen // but we only allow up to this size. 612fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen kMaxAtomSize = 64 * 1024 * 1024, 620dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar}; 630dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 67942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen MPEG4Source(const sp<MPEG4Extractor> &owner, 68942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MetaData> &format, 69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 7048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 7105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 7205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 73c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 7405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 75ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia virtual status_t init(); 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 83cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung virtual bool supportNonblockingRead() { return true; } 8405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 87693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 88693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 907b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 917b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 92942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen // keep the MPEG4Extractor around, since we're referencing its data 93942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen sp<MPEG4Extractor> mOwner; 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 95693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 97693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 9905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 10005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 101c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *mTrex; 10205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 10305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 10405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 10505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 10605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 10705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 11448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 116ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 1233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar bool mIsHEVC; 1246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 1256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 132dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1340024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1350024245e134467d120b40099da16c467dc365e76Andreas Huber 1366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 15105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 15205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 15305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 15405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 15705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 15805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 15905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 16005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 16105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 16205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 16305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 16405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 16505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 16605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 16705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 16805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 169c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t compositionOffset; 170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 17305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 17405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 188090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh explicit MPEG4DataSource(const sp<DataSource> &source); 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 191c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 192c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 195c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 204c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 23250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 23550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 239c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 242bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar if (isInRange(mCachedOffset, mCachedSize, offset, size)) { 24350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 250c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 25150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 258c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 26850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 27050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 27150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 27350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 27550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 27650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 27850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 27950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 28050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 28150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 28250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 28350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 28450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 285b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false; 286b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 291377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 32918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 33218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 334371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 33518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 336371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 33818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 341e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 342e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 34318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 34618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 352dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 35848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 35948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 36048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 36148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 36248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 36348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 36448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 36548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 36648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 36748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 36848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 36948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 37048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 37148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 372693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 373c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 374928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound(false), 375928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound(false), 37605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 377bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 378fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 379bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia mIsQT(false), 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 38172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 382dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 383dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 4008da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 405ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 406ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 407ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 408ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 41205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 41305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 41405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 41505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 41605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4177be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 4187be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 4197be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 42072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4217be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4227be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 42372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4247be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4257be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 429ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 440a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 461371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 462371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 463371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 464371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 472423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen // MPEG2 tracks do not provide CSD, so read the stream header 473423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) { 474423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen off64_t offset; 475423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen size_t size; 476423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen if (track->sampleTable->getMetaDataForSample( 477423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) { 478423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen if (size > kMaxTrackHeaderSize) { 479423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen size = kMaxTrackHeaderSize; 480423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen } 481423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen uint8_t header[kMaxTrackHeaderSize]; 482423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) { 483423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen track->meta->setData(kKeyStreamHeader, 'mdat', header, size); 484423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen } 485423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen } 486423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen } 487423e74647d1b8fd8b2905356af1fc2b1c67a0f3fMarco Nelissen 48805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 48905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 49005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 49105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 49205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 49305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 49405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 49505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 49605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 49705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 4980d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen if (track->timescale != 0 && 4990d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen track->sampleTable->findThumbnailSample(&sampleIndex) == OK 50005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 50105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 50205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 50305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 50405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 50505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 50605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 5077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5087e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5097e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5107e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 51548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 51648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 51748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 51848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 51948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 52048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 52148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 523bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 524bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 527c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 529928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang bool sawMoovOrSidx = false; 530928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 531928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) { 532a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 53305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 534a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 5354ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 5364ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 5374ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 538a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 539a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 540ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset); 541a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 542a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 543928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } else if (err == UNKNOWN_ERROR) { 544928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang sawMoovOrSidx = true; 54505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5477be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 548bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 54955fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia if (findTrackByMimePrefix("video/") != NULL) { 550bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 551bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 55255fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia } else if (findTrackByMimePrefix("audio/") != NULL) { 55372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 55455fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia } else { 55555fe26abb4e3fe701c01b130fee4a5919f8edcbfWei Jia mFileMetaData->setCString(kKeyMIMEType, "application/octet-stream"); 55672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 557bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 558bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 561bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 562ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 563ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 564c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen uint64_t psshsize = 0; 565ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 566ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 567ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 568c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (psshsize > 0 && psshsize <= UINT32_MAX) { 569ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 5706a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (!buf) { 5716a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 5726a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 5736a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 574ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 575ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 576ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 577ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 578ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 579ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 580ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 581ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 582ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 583bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 595dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 60640d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh const sp<DataSource> &DataSource, uint8_t *numOfBytes) { 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 615dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 616dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 62584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 62684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 725dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 727dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 728dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 729dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 730dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 731dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 732dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 733dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 734dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 7358da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 7368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 7378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 7388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 739f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 740dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 741f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 747dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 748dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 749dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 750dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 751dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 752dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 753dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 754dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 755dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 756dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 76472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 76572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 76672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 76872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 76972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 77072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 77172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 77272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 77372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 77472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 77572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 77672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 77772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 77872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 77972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 78072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 78172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 7828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) { 7838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return path.size() >= 2 7848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[0] == FOURCC('m', 'o', 'o', 'v') 7858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[1] == FOURCC('m', 'e', 't', 'a') 7868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && (depth == 2 7878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || (depth == 3 788ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang && (path[2] == FOURCC('h', 'd', 'l', 'r') 789ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang || path[2] == FOURCC('i', 'l', 's', 't') 7908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || path[2] == FOURCC('k', 'e', 'y', 's')))); 7918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 7928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 79372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 7943724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissenstatic bool convertTimeToDate(int64_t time_1904, String8 *s) { 7953724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen // delta between mpeg4 time and unix epoch time 7963724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen static const int64_t delta = (((66 * 365 + 17) * 24) * 3600); 7973724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (time_1904 < INT64_MIN + delta) { 7983724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return false; 7993724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 8003724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen time_t time_1970 = time_1904 - delta; 80172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 80272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 8033724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen struct tm* tm = gmtime(&time_1970); 8043724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (tm != NULL && 8053724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) { 8063724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen s->setTo(tmp); 8073724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return true; 8083724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 8093724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return false; 81072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 81172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 812c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 813ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth); 814452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 815452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (*offset < 0) { 816452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 817452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 818452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 819dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen if (depth > 100) { 820dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen ALOGE("b/27456299"); 821dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen return ERROR_MALFORMED; 822dd2d81b49d22642b15ac6dcbc5ad59d0c6f5c227Marco Nelissen } 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 82434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 8282d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer int32_t chunk_type = ntohl(hdr[1]); 829c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 83234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 83771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 83871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 83971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 84071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 84171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 842a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 843a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 844a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 845a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 846a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 847a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 848a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 849a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 850a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 851a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 852a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 853a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 854a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 855a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 856a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 857a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 85871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 85971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 860a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 86171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 866ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth); 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 868b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 869b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe static const char kWhitespace[] = " "; 870b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 871b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 873b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe char buffer[256]; 874b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t n = chunk_size; 875b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (n > sizeof(buffer)) { 876b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe n = sizeof(buffer); 877b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 878b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (mDataSource->readAt(*offset, buffer, n) 879b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe < (ssize_t)n) { 880b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return ERROR_IO; 881b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 882ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 883b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(buffer, n); 884b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 88772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 888452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - *offset) is either 8 or 16 889452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunk_data_size = chunk_size - (data_offset - *offset); 890452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunk_data_size < 0) { 891452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 892452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 893452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 8942fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) { 8952fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen char errMsg[100]; 8962fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size); 8972fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen ALOGE("%s (b/28615448)", errMsg); 8982fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg)); 8992fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen return ERROR_MALFORMED; 9002fae4e4cb6b3039f28810e827de75b0612fadd83Marco Nelissen } 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 903515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 90472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 905c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 90672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 90772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 90872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 90972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 91072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 91172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 91272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 915bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 916bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 91772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 91872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 91972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 92072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 93272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 93372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 934ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 935ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 9360a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 937bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia case FOURCC('w', 'a', 'v', 'e'): 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 9390d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'v') && depth != 0) { 9400d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen ALOGE("moov: depth %d", depth); 9410d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen return ERROR_MALFORMED; 9420d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen } 943928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) { 944928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang // store the offset of the first segment 945928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound = true; 946928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofOffset = *offset; 947928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } 948928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 94950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 950a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 95150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 952b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 953b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 954b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 95550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 95650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 95750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 95850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 95950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 96050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 96150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 9621edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 963f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 964f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 965f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 9661edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 96750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 96850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9696f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 970bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 9710d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen if (depth != 1) { 9720d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen ALOGE("trak: depth %d", depth); 9730d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen return ERROR_MALFORMED; 9740d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen } 9756f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 9766f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 977bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 978bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 979bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 980bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 981bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 982bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 983bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 985bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 986bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 987bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 9886f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 989bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 990bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 991bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 992bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 993c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 9980d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen if (isTrack) { 9990d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen mLastTrack->skipTrack = true; 10000d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen break; 10010d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen } 100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1006bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1007bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1008bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1009bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 10106f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 10110386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia int32_t trackId; 10120386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia // There must be exact one track header per track. 10130386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 10140386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia mLastTrack->skipTrack = true; 10150386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } 10166f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 10176f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 10186f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 10196f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 10206f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 10216f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 10226f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 10236f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 10246f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 10256f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 1026f303d743250d2754209980bb42017b9668cf163fCaroline Tice if (cur) { 1027f303d743250d2754209980bb42017b9668cf163fCaroline Tice cur->next = NULL; 1028f303d743250d2754209980bb42017b9668cf163fCaroline Tice } 10296f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 10306f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 10316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 10326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 10336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 10346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 10356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 1036bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 1037bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1038bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 1039bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 1040bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1041bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 1042bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1044dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1045dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 1046dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1047dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 1048dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 10540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 10550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 10570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 10580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 10590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 10600a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10610a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10620a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 10640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 10650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10660a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10670a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10680a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 10690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 10700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 1071fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 1072210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 10730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 10750a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 10760a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 10770a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10780a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 10790a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 10800a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 10810a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 10840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 10850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 10860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 10870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 10880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10890a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10900a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 10910a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 10920a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10930a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10940a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10950a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1096fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 1097fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 1098fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 10990a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 11000a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 11010a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 11021391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 11031391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 11041391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 11050a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 11060a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 11070a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 11080a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 11090a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 11100a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1111608fe1d6b2ea4d88245a109afe2bfba580881a16Wei Jia int64_t paddingus = duration - (int64_t)(segment_duration + media_time); 1112465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1113465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1114465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1115465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1116465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1117465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 11180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 11190a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 11200a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 11210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 11220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 11230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 11240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11280517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 112948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1135f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1136f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1137f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1138f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 114048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 114148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 114248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 114348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 114448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 114548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11520517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1158ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1159ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1160ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1161ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1166ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1173ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1174ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1175ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1176ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1177ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1178ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1180ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1181ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1182ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1186ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1187ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1188ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1189ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1190ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1191ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1192ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1193ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1194f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1195f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1196f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1197ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1198ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1200ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1201ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1202ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 120320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 12050517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 12060517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1207ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1208ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1209ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 121020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 121220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 121320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1215ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1216ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 12170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 12180517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1219ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1220ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1221ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1222ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1223ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1224ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1225ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1226ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1227ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1228ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1229ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1230ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1231c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (chunk_size < 20 || pssh.datalen > chunk_size - 20) { 1232ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1233ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1234ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1235ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 12368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 12378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 12388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 12398da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1240ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1241ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1242ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1243ab34612a31e82b713ca0ac043e14f68f3788fbdaMarco Nelissen delete[] pssh.data; 1244ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1245ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1246ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1247ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1248ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1249ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1250ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 12530517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 12540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1255202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 126034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1266c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 127320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 127734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 128120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12832e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (!timescale) { 12842e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale should not be ZERO."); 12852e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 12862e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 12872e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1290c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1291c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 129205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 129320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 129434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1299c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1300c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1301c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 130305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 130434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 131005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 131105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1313e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mLastTrack->timescale != 0) { 1314c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1315c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1316c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 131720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 13197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 13207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 13217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 13227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 13237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 13247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 13257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 13267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 13277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 13297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 13307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 13317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 13327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 13347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 13357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 13367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 13377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 13387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 13397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 13407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 13417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 13437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 13447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1351c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1352bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1353bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1354bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 135534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 136220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 13683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 13693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 13703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1371ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 13723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 1373f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1374f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1375f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1376f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 13773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1378ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1379ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 13803b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 13813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 13823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 13833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 13843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 138520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1386c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 138720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 138820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 139020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 139320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1394bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1395bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1396bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1397bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1400e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang case FOURCC('m', 'e', 't', 't'): 1401e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang { 1402e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang *offset += chunk_size; 1403e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang 1404e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang if (mLastTrack == NULL) 1405e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang return ERROR_MALFORMED; 1406e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang 1407e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang sp<ABuffer> buffer = new ABuffer(chunk_data_size); 1408e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang if (buffer->data() == NULL) { 1409e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang return NO_MEMORY; 1410e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang } 1411e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang 1412e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang if (mDataSource->readAt( 1413e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 1414e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang return ERROR_IO; 1415e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang } 1416e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang 1417e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang String8 mimeFormat((const char *)(buffer->data()), chunk_data_size); 1418e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang mLastTrack->meta->setCString(kKeyMIMEType, mimeFormat.string()); 1419e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang 1420e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang break; 1421e0d59b3301623c5ae8f7b6f26451179beb84a64bHangyu Kuang } 142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 142448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 142520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1426371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1428bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a') 1429bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) { 1430bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia // Ignore mp4a embedded in QT wave atom 1431bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia *offset += chunk_size; 1432bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia break; 1433bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 1434bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 143520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1446b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 1447bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia uint16_t version = U16_AT(&buffer[8]); 144848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 145081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 145181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 145281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1453f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1454f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1455f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1456bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia off64_t stop_offset = *offset + chunk_size; 1457bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia *offset = data_offset + sizeof(buffer); 1458bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 1459bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')) { 1460bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (version == 1) { 1461bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (mDataSource->readAt(*offset, buffer, 16) < 16) { 1462bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia return ERROR_IO; 1463bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 1464bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 1465bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#if 0 1466bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(buffer); // samples per packet 1467bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&buffer[4]); // bytes per packet 1468bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&buffer[8]); // bytes per frame 1469bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&buffer[12]); // bytes per sample 1470bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#endif 1471bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia *offset += 16; 1472bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } else if (version == 2) { 1473bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia uint8_t v2buffer[36]; 1474bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (mDataSource->readAt(*offset, v2buffer, 36) < 36) { 1475bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia return ERROR_IO; 1476bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 1477bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 1478bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#if 0 1479bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(v2buffer); // size of struct only 1480bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia sample_rate = (uint32_t)U64_AT(&v2buffer[4]); // audio sample rate 1481bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia num_channels = U32_AT(&v2buffer[12]); // num audio channels 1482bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&v2buffer[16]); // always 0x7f000000 1483bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia sample_size = (uint16_t)U32_AT(&v2buffer[20]); // const bits per channel 1484bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&v2buffer[24]); // format specifc flags 1485bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&v2buffer[28]); // const bytes per audio packet 1486bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia U32_AT(&v2buffer[32]); // const LPCM frames per audio packet 1487bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia#endif 1488bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia *offset += 36; 1489bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 1490bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 1491bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 149248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 149348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 149448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 149548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 149748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 149881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 150020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 150120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 150220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 150720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1508bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1509bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1510bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1511bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 151220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 151320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1516ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1518e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1519e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 152020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 15213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 15223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 152620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 153220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 153320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1535b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 153620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 153720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 153820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1539ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1540a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1541a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1542a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1543a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1544a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1545a6256238d9015c42129fe43791968768fe501efaJames Dong 1546134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1547134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1549f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1550f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1551f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1552ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1553ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1554ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1555ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 155620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 155720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 155820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1559c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 156020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 156120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 156220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 156320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 156420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 156520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1567bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1568bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1569bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1570bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 157120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 157220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 157320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 157420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 157520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 157620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1577274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1578274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1579274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 158020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 158120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 158320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15840517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15850517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 158620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 158720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 158820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 158920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 159020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 159120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 159220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 159320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 159420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1595274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1596274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1597274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 159820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 159920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 160020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 160120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16020517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16030517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 160420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 160520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 160620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 160720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 160820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 160920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 161020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 161220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 161320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1614274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1615274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1616274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 162320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 162420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 162520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1627738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 162849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 162949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 163049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 163149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 163249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1633738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 163405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 163505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 163605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 163705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 163805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 1639beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (max_size > SIZE_MAX - 10 * 2) { 1640beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("max sample size too big: %zu", max_size); 1641beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1642beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 164305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 164405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 164505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 1646beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen uint32_t width, height; 1647beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) || 1648beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) { 164905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1650f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1651f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 1652beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } else { 1653beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // A resolution was specified, check that it's not too big. The values below 1654beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // were chosen so that the calculations below don't cause overflows, they're 1655beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // not indicating that resolutions up to 32kx32k are actually supported. 1656beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (width > 32768 || height > 32768) { 1657beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("can't support %u x %u video", width, height); 1658beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1659beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 166005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1661f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 16624256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 16634256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 166407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) 166507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 166607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar // AVC & HEVC requires compression ratio of at least 2, and uses 1667f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1668f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1669f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1670f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1671f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1672f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 167305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1674f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 167505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1676113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 16774256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 16784256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1679113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1680113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1681113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1682113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1683113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1684949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (nSamples == 0) { 1685949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t trackId; 1686949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 1687949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 1688949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen Trex *t = &mTrex.editItemAt(i); 1689949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (t->track_ID == (uint32_t) trackId) { 1690949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (t->default_sample_duration > 0) { 1691949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t frameRate = 1692949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->timescale / t->default_sample_duration; 1693949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1694949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1695949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen break; 1696949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1697949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1698949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1699949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } else { 1700949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int64_t durationUs; 1701949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1702949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (durationUs > 0) { 1703949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t frameRate = (nSamples * 1000000LL + 1704949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen (durationUs >> 1)) / durationUs; 1705949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1706949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1707113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1708113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1709113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1710113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 171120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 171220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 171320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 171420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 171520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1716274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1717274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1718274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 17190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 172220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17324931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 17334931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 1734274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1735274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1736274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 17370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 17394931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 17404931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 17414931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 17424931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 17434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 17444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 17454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 17464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 17474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 17484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 17494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 175020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 175120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1752274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1753274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1754274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 17550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17560517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 175720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 175820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 175920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 176020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 176120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 176220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 176320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 176420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 176520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 176620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 176720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1768afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // \xA9xyz 1769e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh case FOURCC(0xA9, 'x', 'y', 'z'): 17704948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 17710517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17720517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1773afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // Best case the total data length inside "\xA9xyz" box 1774afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/", 17754948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 17764948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 17774948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 17784948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 17794948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 17804948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17814948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17824948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 17834948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 178423b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney // the string length + language code, and some devices include 178523b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney // an additional 8 bytes of altitude, e.g. +007.186 178623b98e3538529f88cdb758adedeee68408635fcbBryan Mawhinney char buffer[18 + 8]; 17874948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17884948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 17894948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 17904948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 17914948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 17924948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 17934948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17944948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17954948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 17964948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 17974948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 17984948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17994948818cb91176df74c972ac27b2f392b5d148bcJames Dong 18004948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 18014948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 18024948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 18034948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 18044948818cb91176df74c972ac27b2f392b5d148bcJames Dong 180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 18070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 181020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1814c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 181520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 181620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 181920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 182020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 182120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 182220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 182320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 182420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 182520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 182620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 182720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1828f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1829f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1830f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 183120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 183220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 183320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1834ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1835ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1836ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1837ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1838ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1839ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1840ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1841ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1842ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1843ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1844ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1845ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1846ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1847ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1848ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (mPath.size() >= 2 1849ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) { 1850ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar // Check if the video is MPEG2 1851ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar ESDS esds(&buffer[4], chunk_data_size - 4); 1852ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar 1853ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar uint8_t objectTypeIndication; 1854ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) { 1855ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) { 1856ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); 1857ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1858ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1859ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 186020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 186120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 186220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 186346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar case FOURCC('b', 't', 'r', 't'): 186446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar { 186546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar *offset += chunk_size; 1866fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa if (mLastTrack == NULL) { 1867fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa return ERROR_MALFORMED; 1868fd9cc97d4dfe2a2fbce2c0f1704d7a27ce7cbc44Pawin Vongmasa } 186946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 187046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint8_t buffer[12]; 187146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (chunk_data_size != sizeof(buffer)) { 187246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return ERROR_MALFORMED; 187346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 187446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 187546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (mDataSource->readAt( 187646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar data_offset, buffer, chunk_data_size) < chunk_data_size) { 187746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return ERROR_IO; 187846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 187946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 188046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint32_t maxBitrate = U32_AT(&buffer[4]); 188146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint32_t avgBitrate = U32_AT(&buffer[8]); 188246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (maxBitrate > 0 && maxBitrate < INT32_MAX) { 188346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); 188446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 188546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (avgBitrate > 0 && avgBitrate < INT32_MAX) { 188646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate); 188746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 188846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar break; 188946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 189020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 189120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 189220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 18930517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 18940517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1895d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 189620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18976a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 18986a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 18996a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 19006a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 19016a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen 190234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1903d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 190420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 190520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 190620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1907f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1908f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1909f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 191020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1911d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 191220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 191320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 191420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 19163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 19173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 19183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 19196a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 19206a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 19216a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 19226a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 19236a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen 19243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 19253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 19263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 19273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 19283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 1929f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1930f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1931f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 19323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 19333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 19343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 19353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 19363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 19373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 193820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1939244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1940244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 19410517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 194217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 194317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 194417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 194517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 194617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 194717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 194817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 194917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 195017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 195117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 195217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 195317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 195417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 195517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1956ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size); 1957244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1958244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1959244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1960244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1961244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1962244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1963244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1964244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1965f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1966f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1967f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1968244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1969244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1970244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1971244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1972244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 197372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 197472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 19758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stop_offset = *offset + chunk_size; 19768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset = data_offset; 19778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang bool isParsingMetaKeys = underQTMetaPath(mPath, 2); 19788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!isParsingMetaKeys) { 19798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint8_t buffer[4]; 19808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (chunk_data_size < (off64_t)sizeof(buffer)) { 19818ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 19828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 19838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 1984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 19858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 19868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang data_offset, buffer, 4) < 4) { 19878ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 19888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_IO; 19898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 199072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 19918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (U32_AT(buffer) != 0) { 19928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // Should be version 0, flags 0. 1993ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 19948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // If it's not, let's assume this is one of those 19958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // apparently malformed chunks that don't have flags 19968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // and completely different semantics than what's 19978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // in the MPEG4 specs and skip it. 19988ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 19998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 20008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 20018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += sizeof(buffer); 200272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 200372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 200472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 200572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 200672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 200772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 200872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 200972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 2010bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 2011bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 2012bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 2013bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 201472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 201572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 201672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 20175d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 20185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 201972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 202072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 20210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 202372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 2024fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 202572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 202672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 202772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 202872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 202972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 203072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 203172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 203272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 203372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 203472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 203572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 20360517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 20380d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen if (depth != 1) { 20390d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen ALOGE("mvhd: depth %d", depth); 20400d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen return ERROR_MALFORMED; 20410d13824315b0491d44e9c6eb5db06489ab0fcc20Marco Nelissen } 2042c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 204372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 204472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 204572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2046c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 204772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 204872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 204972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 205072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 205172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 205272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2053fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 2054c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 205572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 205672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 2057fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 2058c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 2059c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 2060c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 2061c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2062bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 2063bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 206472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 206572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 2066fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 2067c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 2068c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 2069c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 2070c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2071c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 2072c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 20733724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) { 2074c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 207572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 207672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 207772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 20783724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (convertTimeToDate(creationTime, &s)) { 20793724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen mFileMetaData->setCString(kKeyDate, s.string()); 20803724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 208172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 208272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 208372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 208472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 208572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2086c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 2087c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 2088c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 2089c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2090c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 2091c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2092c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2093c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2094c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 2095c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 2096c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 2097c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 2098c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2099c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2100c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2101c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 2102c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 2103c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 2104c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 2105c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2106c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2107c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 2108c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 2109c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 2110c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2111c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 2112c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 2113c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 2114c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 2115c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 2116c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 2117c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2118c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 2119c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 2120c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2121c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2122c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2123e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 2124c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 2125c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2126c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2127c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2128c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2129c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2130dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 2131dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 2132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 2133928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 2134928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound = true; 2135928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 2136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 2137dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 2138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 2139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2141dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 2142dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 2143dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2144dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2145dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 2146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 21483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 21493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 21500517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21510517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2152ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang if (underQTMetaPath(mPath, 3)) { 2153ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang break; 2154ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang } 2155ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang 21563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 21573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 21583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 21593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 21603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 21633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 2164e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 2165e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 2166e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 2167cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar if (mLastTrack != NULL) { 2168cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 2169cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar } 21703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 21733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang case FOURCC('k', 'e', 'y', 's'): 21768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang { 21778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 21788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 21798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 2180ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia status_t err = parseQTMetaKey(data_offset, chunk_data_size); 2181ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (err != OK) { 2182ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return err; 2183ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 21848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 21858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang break; 21868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 21878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 2188c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 2189c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 2190c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 2191c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2192c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 2193c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2194c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2195c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 2196c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 2197c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 2198c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 2199c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 2200c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 2201c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2202c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2203c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 2204c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2205c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2206c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 22077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 22087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 2209f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2210f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2211f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 22123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 22133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 22143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 22153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 22163b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 22173b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 22183b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 22193b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 22200e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) { 2221dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake return ERROR_MALFORMED; 2222dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake } 2223dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake 22248da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 22258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 22268da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 22278da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 22283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 22293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 22303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 22313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 22323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 22333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 22343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 22353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 22363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 22373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 22380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 22390517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 22403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 22413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 22423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 22433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 22443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 22453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 22463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 22477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 22487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 22497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 22507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 22517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 2252515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 2253515e855eae78aa495da58356486aaa666cb57fd1James Dong { 22540517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 22550517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2256515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 2257635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, 2258635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert chunk_data_size, data_offset); 22591e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake 2260635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) { 22611e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake return ERROR_MALFORMED; 22621e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake } 22631552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 22646a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 22656a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 22666a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 22676a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 2268515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 22691552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 2270515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 2271515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2272515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 227397d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake if (chunk_data_size <= kSkipBytesOfDataBox) { 227497d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake return ERROR_MALFORMED; 227597d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake } 227697d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake 2277515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 2278515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 22791552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 2280515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2281515e855eae78aa495da58356486aaa666cb57fd1James Dong 2282515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 2283515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2284515e855eae78aa495da58356486aaa666cb57fd1James Dong 228558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar case FOURCC('c', 'o', 'l', 'r'): 228658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar { 228758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar *offset += chunk_size; 228858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd') 228958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // ignore otherwise 229058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) { 229158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar status_t err = parseColorInfo(data_offset, chunk_data_size); 229258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (err != OK) { 229358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return err; 229458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 229558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 229658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 229758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar break; 229858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 229958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2300fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2301fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2302fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2303fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2304fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2305fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2306fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 23070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 23080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2309fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 2310fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2311fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 2312fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 2313fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2314fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2315fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2316fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2317fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2318328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 2319328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 23200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 23210517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2322328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 2323328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 2324328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2325328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2326328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 2327328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2328328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 2329328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2330328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 23315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 23325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 23335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 23345d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 23355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 23365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 23375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 23385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 23395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 234005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 234105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 2342ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia status_t err = parseSegmentIndex(data_offset, chunk_data_size); 2343ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (err != OK) { 2344ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return err; 2345ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 234605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 234705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 234805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 234905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2350bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa case FOURCC('a', 'c', '-', '3'): 2351bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa { 2352bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa *offset += chunk_size; 2353bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return parseAC3SampleEntry(data_offset); 2354bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2355bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2356bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia case FOURCC('f', 't', 'y', 'p'): 2357bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia { 2358bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (chunk_data_size < 8 || depth != 0) { 2359bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia return ERROR_MALFORMED; 2360bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 2361bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 2362bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia off64_t stop_offset = *offset + chunk_size; 2363bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4; 2364bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 2365bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (i == 1) { 2366bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia // Skip this index, it refers to the minorVersion, 2367bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia // not a brand. 2368bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia continue; 2369bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 2370bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 2371bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia uint32_t brand; 2372bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (mDataSource->readAt(data_offset + 4 * i, &brand, 4) < 4) { 2373bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia return ERROR_MALFORMED; 2374bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 2375bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 2376bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia brand = ntohl(brand); 2377bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia if (brand == FOURCC('q', 't', ' ', ' ')) { 2378bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia mIsQT = true; 2379bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia break; 2380bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 2381bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 2382bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 2383bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia *offset = stop_offset; 2384bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 2385bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia break; 2386bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia } 2387bb0b734ca158c2129d7c31449a3eedcd76dcd03cWei Jia 238820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 238920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 23908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // check if we're parsing 'ilst' for meta keys 23918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // if so, treat type as a number (key-id). 23928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 2393ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size); 2394ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (err != OK) { 2395ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return err; 2396ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 23978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 239920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 240020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 240120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 240220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 240320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 240420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 240520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 240620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2407bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasastatus_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) { 2408bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // skip 16 bytes: 2409bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 6-byte reserved, 2410bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 2-byte data reference index, 2411bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 8-byte reserved 2412bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa offset += 16; 2413bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa uint16_t channelCount; 2414bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (!mDataSource->getUInt16(offset, &channelCount)) { 2415bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2416bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2417bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // skip 8 bytes: 2418bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 2-byte channelCount, 2419bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 2-byte sample size, 2420bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 4-byte reserved 2421bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa offset += 8; 2422bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa uint16_t sampleRate; 2423bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (!mDataSource->getUInt16(offset, &sampleRate)) { 2424bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate"); 2425bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2426bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2427bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2428bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // skip 4 bytes: 2429bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 2-byte sampleRate, 2430bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 2-byte reserved 2431bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa offset += 4; 2432bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return parseAC3SpecificBox(offset, sampleRate); 2433bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa} 2434bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2435bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasastatus_t MPEG4Extractor::parseAC3SpecificBox( 2436bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa off64_t offset, uint16_t sampleRate) { 2437bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa uint32_t size; 2438bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 4-byte size 2439bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 4-byte type 2440bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // + 3-byte payload 2441bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa const uint32_t kAC3SpecificBoxSize = 11; 2442bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (!mDataSource->getUInt32(offset, &size) || size < kAC3SpecificBoxSize) { 2443bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read specific box size"); 2444bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2445bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2446bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2447bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa offset += 4; 2448bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa uint32_t type; 2449bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'a', 'c', '3')) { 2450bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3"); 2451bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2452bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2453bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2454bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa offset += 4; 2455bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa const uint32_t kAC3SpecificBoxPayloadSize = 3; 2456bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa uint8_t chunk[kAC3SpecificBoxPayloadSize]; 2457bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (mDataSource->readAt(offset, chunk, sizeof(chunk)) != sizeof(chunk)) { 2458bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGE("MPEG4Extractor: error while reading ac-3 specific block: bitstream fields"); 2459bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2460bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2461bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2462bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ABitReader br(chunk, sizeof(chunk)); 2463bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5}; 2464bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa static const unsigned sampleRateTable[] = {48000, 44100, 32000}; 2465bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2466bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned fscod = br.getBits(2); 2467bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (fscod == 3) { 2468bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGE("Incorrect fscod (3) in AC3 header"); 2469bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2470bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2471bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned boxSampleRate = sampleRateTable[fscod]; 2472bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (boxSampleRate != sampleRate) { 2473bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d", 2474bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa boxSampleRate, sampleRate); 2475bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2476bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2477bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2478bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned bsid = br.getBits(5); 2479bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (bsid > 8) { 2480bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?"); 2481bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2482bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2483bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2484bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa // skip 2485bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned bsmod __unused = br.getBits(3); 2486bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2487bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned acmod = br.getBits(3); 2488bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned lfeon = br.getBits(1); 2489bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa unsigned channelCount = channelCountTable[acmod] + lfeon; 2490bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 2491bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa if (mLastTrack == NULL) { 2492bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return ERROR_MALFORMED; 2493bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa } 2494bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); 2495bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa mLastTrack->meta->setInt32(kKeyChannelCount, channelCount); 2496bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 2497bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa return OK; 2498bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa} 2499bcbd7bce03772a22c2965dab636c1f67b7a655f5Pawin Vongmasa 250005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 250105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 250205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 250305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 250405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 250505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 250605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 250705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 250805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 250905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 251005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 251105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 251205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 251305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 251405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 251505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 251605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 251705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 251805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 251905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 252005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 252105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 252205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 252305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 252405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 252505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 252605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 2527e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (timeScale == 0) 2528e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake return ERROR_MALFORMED; 252905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 253005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 253105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 253205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 253305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 253405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 253505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 253605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 253705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 253805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 253905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 254005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 254105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 254205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 254305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 254405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 254505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 254605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 254705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 254805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 254905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 255005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 255105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 255205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 255305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 255405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 255505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 255605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 255705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 255805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 255905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 256005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 256105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 256205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 256305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2564a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 256505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 256605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 256705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 256805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 256905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 257005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 257105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 257205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 257305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 257405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 257505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 257605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 257705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 257805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 257905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 258005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 258105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 258205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 258305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 258405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 258505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 258605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 258705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 258805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 258905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 259005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 259105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 259205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 259305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 259405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 259505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 25963f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 25973f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 25983f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 25993f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 260005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 260105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 260205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 260305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 260405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 260505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 260605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 260705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 260805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 260905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2610c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 261105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2612f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2613f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2614f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 261505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 261605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2617c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 261805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 261905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 262005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 262105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 26228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) { 26238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size < 8) { 26248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t count; 26288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &count)) { 26298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mMetaKeyMap.size() > 0) { 26338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGW("'keys' atom seen again, discarding existing entries"); 26348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.clear(); 26358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t keyOffset = offset + 8; 26388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stopOffset = offset + size; 26398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang for (size_t i = 1; i <= count; i++) { 26408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyOffset + 8 > stopOffset) { 26418cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t keySize; 26458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset, &keySize) 26468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keySize < 8 26478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keyOffset + keySize > stopOffset) { 26488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t type; 26528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset + 4, &type) 26538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || type != FOURCC('m', 'd', 't', 'a')) { 26548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keySize -= 8; 26588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += 8; 26598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang sp<ABuffer> keyData = new ABuffer(keySize); 26618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyData->data() == NULL) { 26628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 26658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset, keyData->data(), keySize) < (ssize_t) keySize) { 26668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang AString key((const char *)keyData->data(), keySize); 26708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.add(i, key); 26718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += keySize; 26738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 26758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 26768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 26778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal( 26788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang int32_t keyId, off64_t offset, size_t size) { 26798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ssize_t index = mMetaKeyMap.indexOfKey(keyId); 26808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (index < 0) { 26818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // corresponding key is not present, ignore 26828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 268405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 26858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size <= 16) { 26868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataSize; 26898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &dataSize) 26908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || dataSize > size || dataSize <= 16) { 26918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t atomFourCC; 26948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &atomFourCC) 26958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || atomFourCC != FOURCC('d', 'a', 't', 'a')) { 26968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 26978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 26988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataType; 26998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 8, &dataType) 27008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || ((dataType & 0xff000000) != 0)) { 27018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // not well-known type 27028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 27038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 27048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 27058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang dataSize -= 16; 27068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang offset += 16; 27078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 27088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (dataType == 23 && dataSize >= 4) { 27098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // BE Float32 27108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t val; 27118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &val)) { 27128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 27138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 27148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) { 27158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val); 27168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 27174dbff11975e737482537e1636051690188f3fbc4Praveen Chavan } else if (dataType == 67 && dataSize >= 4) { 27184dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // BE signed int32 27194dbff11975e737482537e1636051690188f3fbc4Praveen Chavan uint32_t val; 27204dbff11975e737482537e1636051690188f3fbc4Praveen Chavan if (!mDataSource->getUInt32(offset, &val)) { 27214dbff11975e737482537e1636051690188f3fbc4Praveen Chavan return ERROR_MALFORMED; 27224dbff11975e737482537e1636051690188f3fbc4Praveen Chavan } 27234dbff11975e737482537e1636051690188f3fbc4Praveen Chavan if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) { 27244dbff11975e737482537e1636051690188f3fbc4Praveen Chavan mFileMetaData->setInt32(kKeyTemporalLayerCount, val); 27254dbff11975e737482537e1636051690188f3fbc4Praveen Chavan } 27268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } else { 27278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // add more keys if needed 27288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGV("ignoring key: type %d, size %d", dataType, dataSize); 27298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 27308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 27318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 27328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 273305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2734ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2735c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2736ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2737ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2738ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2739ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2740ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2741ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2742ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2743ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2744ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2745ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2746ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2747ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2748ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2749c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2750ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2751ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2752ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2753ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2754ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2755ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2756ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2757ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2758b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint64_t ctime __unused, mtime __unused, duration __unused; 2759ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2760ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2761ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2762ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2763ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2764ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2765ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 276604022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2767ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2768ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2769ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2770ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 277104022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 277204022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2773ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2774ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2775f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2776f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2777f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2778ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2779ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2780ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2781ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2782ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2783ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2784ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2785ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2786ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2787b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2788b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2789b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 2790df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2791ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2792df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2793ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2794ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2795ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2796ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2797ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2798ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2799ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2800ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2801ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2802ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2803ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2804ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2805ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2806ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2807ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2808ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 28095ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2810ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2811ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2812ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2813ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2814ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2815ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2816ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2817b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2818b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2819ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2820ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2821b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2822b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2823ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2824ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2825ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2826ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2827fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 2828d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia if (size == 0) { 2829d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia return OK; 2830d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia } 2831d20e1f932277eed35f9ec423f134b4a60b8f9b85Wei Jia 2832c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich if (size < 4 || size == SIZE_MAX) { 283372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 283472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 283572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 28368da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 28378da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 28388da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 28398da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 284072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 284172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 284272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 284372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 284472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 284572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 284672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 284772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 284872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 284972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 285072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 28515d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 28525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 2853ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("meta: %s @ %lld", chunk, (long long)offset); 28542d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer switch ((int32_t)mPath[4]) { 285572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 285672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 285772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 285872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 285972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 286072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 286172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 286272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 286372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 286472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 286566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 286666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 286766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 286866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 286966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 287072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 287172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 287272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 287372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 287472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 287572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 287672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 287772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 287872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 287972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 288072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 288172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 288272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 288372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 288472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 288572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 288672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 288772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 288872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 288972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 289072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 289172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 289272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 289372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 289472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 289526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 289626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 289726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 289826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 289926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 290011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 290111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 290211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 290311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 290411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 290511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 290611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 290711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 290811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 290911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 291011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 291172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 291272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 291372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 291472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2915afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2916afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2917afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 291872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 291972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 292072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 292172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 292272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 292326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 292426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2925afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 292626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2927afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2928afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2929afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 293026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 293126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 293226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 293326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 293426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 29355d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 29365d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 29375d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 29385d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 29395d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 29405d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 29415d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 29425d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 29435d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 29445d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 29455d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 29465cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia if (size < 8) { 29475cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia delete[] buffer; 29485cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia buffer = NULL; 29495cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia ALOGE("b/24346430"); 29505cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia return ERROR_MALFORMED; 29515cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia } 29525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 29535d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 29545d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 29558c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 29568c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 29578c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 29588c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 29598c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 29608c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 29618c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 29628c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 29638c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 29648c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 29658c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 29668c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 29678c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 29688c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 29698c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 2970a0721999eccd22d900eb6dec7e48f835f28ce999Marco Nelissen if (mLastTrack == NULL) { 2971a0721999eccd22d900eb6dec7e48f835f28ce999Marco Nelissen delete[] buffer; 2972f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2973a0721999eccd22d900eb6dec7e48f835f28ce999Marco Nelissen } 2974f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 29758c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 29768c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 29778c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 29785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 29798c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 29805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 29815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 29825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 29835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 29845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 29855d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 298626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 298772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 298872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 298972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 299072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2991328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 299272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 299372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 299472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 299572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 299672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 299772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 299826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 299926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 300026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 300126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 300226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 300326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 300426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 300526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 300626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 300772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 300826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 300972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 301072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 301126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 301226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 301326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 301426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 301526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 301626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 301772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 301872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 301972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 302072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 302172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 302272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 302372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 302472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 302572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 302672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 302772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 302872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 302972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 303072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 303172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 303258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { 303358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) { 303458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 303558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 303658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 303758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 303858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (buffer == NULL) { 303958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 304058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 304158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) { 304258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 304358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 304458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 304558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_IO; 304658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 304758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 304858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t type = U32_AT(&buffer[0]); 304958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11) 305051a0ff56f49faf1a19281f6d786fe18bf84794c6Hangyu Kuang || (type == FOURCC('n', 'c', 'l', 'c') && size >= 10)) { 305158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t primaries = U16_AT(&buffer[4]); 305258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t transfer = U16_AT(&buffer[6]); 305358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t coeffs = U16_AT(&buffer[8]); 305458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128); 305558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 305658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorAspects aspects; 305758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorUtils::convertIsoColorAspectsToCodecAspects( 305858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar primaries, transfer, coeffs, fullRange, aspects); 305958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 306058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // only store the first color specification 306158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { 306258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); 306358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); 306458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); 306558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); 306658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 306758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 306858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 306958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 307058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 307158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 307258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return OK; 307358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar} 307458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 3075fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 30765cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake if (size < 4 || size == SIZE_MAX) { 3077fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 3078fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3079fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 30805cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 30818da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 30828da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 30838da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 3084fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 3085fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 3086fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 3087fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 3088fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3089fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 3090fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3091fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3092fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 3093fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 3094fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 3095fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 3096fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 3097fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3098fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3099fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 3100fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 3101fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 3102fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3103fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3104fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 3105fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 3106fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 3107fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3108fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3109fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 3110fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 3111fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 3112fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3113fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3114fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 3115fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 3116fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 3117fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 3118fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 3119fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3120fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 3121fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3122fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3123fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 3124fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3125fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3126fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 3127fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 31286ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang if (size < 6) { 31296ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang delete[] buffer; 31306ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang buffer = NULL; 31316ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang ALOGE("b/62133227"); 31326ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang android_errorWriteLog(0x534e4554, "62133227"); 31336ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang return ERROR_MALFORMED; 31346ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang } 3135fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 3136fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 3137fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3138fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 3139fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 3140fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3141fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 3142fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3143fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3144fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3145fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3146fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 3147fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 3148fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3149fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3150fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 3151fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 3152fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 3153fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 3154fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3155fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 31569458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake if (size < 6) { 31576ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang delete[] buffer; 31586ace94d2952eac82fc4c86aa6d585258248bf18cDongwon Kang buffer = NULL; 31599458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake return ERROR_MALFORMED; 31609458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake } 31619458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake 3162fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 3163fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 3164fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 3165fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 3166fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 3167fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 3168fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 3169fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3170fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 3171fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3172fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3173fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 3174fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 3175fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 3176fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 3177fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 3178fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3179fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 3180fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 3181fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 3182fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3183fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3184fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 31855cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake buffer[size] = 0; 3186fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 3187fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 3188fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 3189fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 3190fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 3191fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3192fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 3193fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3194fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 3195fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 3196fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3197fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 3198fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 3199fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 3200328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 3201328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 3202328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3203328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 3204328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 3205328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 3206328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 3207328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 3208328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 3209328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 3210328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 3211328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 3212328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 3213328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 3214328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 3215328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 3216328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 3217328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 3218328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 3219328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 3220328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 3221328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 3222328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 3223328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3224328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 3225328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 3226328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 3227328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 3228328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 3229328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 3230328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 3231328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3232328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 3233328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 3234328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 3235328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 3236328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3237328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 3238328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 3239328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 3240328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3241328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 3242328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 3243328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 3244328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3245328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 3246328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 3247328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 3248328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3249328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 3250328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 3251328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 3252328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 3253328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 3254328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 3255328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 3256b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) { 325720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 325820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 3259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 326020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 326120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 326220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 326320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 326420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 3265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 326620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 326720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 326820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 326920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 327020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 327120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3272371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 3273371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 3274371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 3275371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3276c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3277c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 3278c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 3279c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 3280c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 3281949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen Trex *t = &mTrex.editItemAt(i); 3282c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 3283c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 3284c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 3285c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 3286c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 32870386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } else { 32880386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia ALOGE("b/21657957"); 32890386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia return NULL; 3290c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 3291c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3292a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 3293ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3294a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const char *mime; 3295a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findCString(kKeyMIMEType, &mime)) { 3296a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3297a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3298a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3299a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 3300a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 3301a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 3302a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 3303a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) { 3304a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3305a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3306a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3307a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 3308a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3309a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 3310a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3311a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3312a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 3313a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 3314a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 3315a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 3316a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) { 3317a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3318a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3319a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3320a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 3321a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3322a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 22 || ptr[0] != 1) { // configurationVersion == 1 3323a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3324a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3325a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3326a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3327ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia sp<MPEG4Source> source = new MPEG4Source(this, 332805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 3329c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 3330ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (source->init() != OK) { 3331ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return NULL; 3332ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 3333ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return source; 333420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 333520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3336bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 3337bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 3338bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 3339bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3340bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3341bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 3342bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 3343bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 3344bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 3345bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 3346bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 3347bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 3348bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 33493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 33503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 33513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 33523b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 33533b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3354bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 3355ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) 3356bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 3357bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 3358bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 3359bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 3360bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 3361bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 3362bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3363ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 3364169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 3365ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 3366169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 3367169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 3368169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 33692e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (track->timescale == 0) { 33702e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale invalid."); 33712e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 33722e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 33732e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 3374bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 3375bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 3376bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3377f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 3378f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 3379f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 3380f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 3381f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 3382f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 3383f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 3384f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 3385f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 3386f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 3387f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 3388f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 3389f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 3390f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 3391f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 3392f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 3393f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 3394f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 3395f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 3396f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 3397f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 3398f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 3399f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 3400f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 3401f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 3402f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 3403f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 3404f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 3405f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 3406f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 3407f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 3408f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 3409f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 3410f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3411f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 3412f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3413f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 3414f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 3415f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 3416f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 3417f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 3418f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 3419f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 3420f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 3421f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3422f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 3423f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 3424f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 3425f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3426f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 3427f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 3428f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3429ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 3430ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 3431ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 343281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 343381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 343481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 343581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 343681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 343781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 343881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 343981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 3440f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3441f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3442f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 344381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 344481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 344581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 344681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 3447633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 3448633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 3449633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 3450633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 345129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 3452633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 3453633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 3454633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 3455ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 3456ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 3457ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 3458ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 3459ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3460ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3461ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3462b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 3463ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar printf("ESD of size %zu\n", csd_size); 3464b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(csd, csd_size); 3465b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 3466ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3467a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 3468a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 3469a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 3470a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 3471a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3472a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 3473a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 3474a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3475ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 3476ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3477ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3478ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 347900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 348000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 348100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 348200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 348300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 3484aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 3485aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 3486ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3487aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 3488aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 3489ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3490ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3491f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3492f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3493f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3494db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 3495db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 3496db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 3497aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 3498aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 3499ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 3500ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 3501ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 35028e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 28) return ERROR_MALFORMED; 3503aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 3504aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 3505ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 35068e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3507595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 350800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 350900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 351000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 3511ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3512ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 351300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 351400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 3515595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 3516f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 35178e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 351800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 3519b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t extSampleRate __unused; 352000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 352100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 3522595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 3523595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 35248e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 24) return ERROR_MALFORMED; 352500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 352600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 352700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 352800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 352900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 353000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 3531595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 353200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 353300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 3534ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3535ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3536f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 3537f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 3538f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 3539f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 3540f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 3541f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 3542f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 3543f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 3544f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 3545f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 3546f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3547f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 3548f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 3549f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3550f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 3551f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 3552f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 3553f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 3554f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3555f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 3556f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 3557f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3558f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3559f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 3560f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 35618e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3562f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 3563f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3564f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 35658e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 6) return ERROR_MALFORMED; 3566f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 3567f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3568f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3569f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 3570f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 3571f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 35728e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 2) return ERROR_MALFORMED; 3573b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t frameLengthFlag __unused = br.getBits(1); 3574f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3575f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 3576f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3577f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 35788e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 14) return ERROR_MALFORMED; 3579b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t coreCoderDelay __unused = br.getBits(14); 3580f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3581f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 358245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 358345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 358445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 358545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 358645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 358745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 358845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 358945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 359045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 359145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 359245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 359345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 359445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 359545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 359645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 359745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 35988e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 359945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 360045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 360145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 360245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 360345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 3604f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 360545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 3606f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 3607f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 36088e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 32) { 36098e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 36108e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen } 3611b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t ElementInstanceTag __unused = br.getBits(4); 3612b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t Profile __unused = br.getBits(2); 3613b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SamplingFrequencyIndex __unused = br.getBits(4); 3614f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 3615f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 3616f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 3617f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 3618b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumAssocDataElements __unused = br.getBits(3); 3619b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumValidCcElements __unused = br.getBits(4); 3620f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3621f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 36228e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen 3623f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 36248e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3625b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MonoMixdownElementNumber __unused = br.getBits(4); 3626f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3627f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 36288e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3629f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 3630f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 36318e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3632b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t StereoMixdownElementNumber __unused = br.getBits(4); 3633f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3634f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 36358e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3636f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 3637f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 36388e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 3) return ERROR_MALFORMED; 3639b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MatrixMixdownIndex __unused = br.getBits(2); 3640b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t PseudoSurroundEnable __unused = br.getBits(1); 3641f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3642f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3643f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 3644f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 36458e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3646f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 3647b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t FrontElementTagSelect __unused = br.getBits(4); 3648f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 3649f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3650f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3651f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 36528e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3653f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 3654b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SideElementTagSelect __unused = br.getBits(4); 3655f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 3656f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3657f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3658f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 36598e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3660f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 3661b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t BackElementTagSelect __unused = br.getBits(4); 3662f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 3663f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3664f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 3665f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3666f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 36678e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3668b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t LfeElementTagSelect __unused = br.getBits(4); 3669f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 3670f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3671f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 3672f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 3673f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 3674f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3675f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3676f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3677f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3678ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 3679ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 3680ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3681ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3682f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3683f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3684f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3685ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 3686ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 3687ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3688ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 36893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 3690ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 3691ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3692ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3693ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 3694ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3695ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 3696ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 3697ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3698ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 36993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 3700ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 3701ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3702ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3703ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 3704ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3705ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 3706ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 3707ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 370820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 370920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 371020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 3711942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 371220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 3713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 371448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 371505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 371605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 3717c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 371805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 3719942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 3720942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 372120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 372248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 372320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 372420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 372505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 372605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 3727c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 372805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 372905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 3730ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia mNextMoofOffset(-1), 373105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 3732ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 3733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 3734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 3735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 373620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 37373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 37386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 373920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 374020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 374120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 3742dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 37430024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 3744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3745c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 3746c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 374848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 3749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 3750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 3751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 3752ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 3753ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 3754ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 3755ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 3756ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 3757ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3758ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 375920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 376020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 3761dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 376220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 376318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 37643b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 37656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 37666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 37676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 37686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 37696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 37706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 37716064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 37726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 37736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 37746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3775ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 37766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 37776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 37786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 37793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 37803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 37813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 37823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 37833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 37843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 37853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 37863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3787a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia CHECK(size >= 22); 37883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 37893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 37903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 37916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 379205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 379305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 379405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3795ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia} 3796ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia 3797ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jiastatus_t MPEG4Source::init() { 379805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 379905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 3800ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return parseChunk(&offset); 380105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 3802ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return OK; 380320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 380420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 380520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 380620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 380720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 380820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3809ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3810ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 381120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 381220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 381320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 38147b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 38157b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 381720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 381820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3819dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 382020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3821dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 382220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3823dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 382420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 382520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3826afd492436efc7f66b958da14659b52232efa5910Marco Nelissen int32_t tmp; 3827afd492436efc7f66b958da14659b52232efa5910Marco Nelissen CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp)); 3828afd492436efc7f66b958da14659b52232efa5910Marco Nelissen size_t max_size = tmp; 382920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3830afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // A somewhat arbitrary limit that should be sufficient for 8k video frames 3831afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // If you see the message below for a valid input stream: increase the limit 3832cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung const size_t kMaxBufferSize = 64 * 1024 * 1024; 3833cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung if (max_size > kMaxBufferSize) { 3834cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize); 3835cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung return ERROR_MALFORMED; 3836cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung } 3837cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung if (max_size == 0) { 3838cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung ALOGE("zero max input size"); 3839afd492436efc7f66b958da14659b52232efa5910Marco Nelissen return ERROR_MALFORMED; 3840afd492436efc7f66b958da14659b52232efa5910Marco Nelissen } 38410024245e134467d120b40099da16c467dc365e76Andreas Huber 3842cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize. 3843cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung const size_t kMaxBuffers = 8; 3844cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung const size_t buffers = min(kMaxBufferSize / max_size, kMaxBuffers); 3845cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung mGroup = new MediaBufferGroup(buffers, max_size); 38468da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 38478da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 38488da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 3849afd492436efc7f66b958da14659b52232efa5910Marco Nelissen delete mGroup; 3850afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = NULL; 38518da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 38528da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 385320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 385420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 385520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 385620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 385720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 385820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 385920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 38607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 38617b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 386320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 386420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 386520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 386620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 386720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 386820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38690024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 38700024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 38710024245e134467d120b40099da16c467dc365e76Andreas Huber 387220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 387320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 387420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 387520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 387620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 387720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 387820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 387920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 388020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 388105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 388205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 388305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 388405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 388505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 388605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 388705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 388805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 388905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 389005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 389105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 389205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 389305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 389405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 389505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 389605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 389705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 389805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 389905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 390005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 390205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 390305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 390405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 3908ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset); 390905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 391705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 39253f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 39263f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 39273f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 39283f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 39292bdbb166a4063a91bab75e50170695370004feccWei Jia // no more box to the end of file. 39302bdbb166a4063a91bab75e50170695370004feccWei Jia break; 39313f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 39323f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 39333f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 3934ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (chunk_size == 1) { 3935ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box 3936ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia // which is defined in 4.2 Object Structure. 3937ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia // When chunk_size==1, 8 bytes follows as "largesize". 3938ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 3939ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return ERROR_IO; 3940ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 3941ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia chunk_size = ntoh64(chunk_size); 3942ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (chunk_size < 16) { 3943ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia // The smallest valid chunk is 16 bytes long in this case. 3944ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return ERROR_MALFORMED; 3945ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 3946ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } else if (chunk_size == 0) { 3947ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia // next box extends to end of file. 3948ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } else if (chunk_size < 8) { 3949ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia // The smallest valid chunk is 8 bytes long in this case. 3950ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return ERROR_MALFORMED; 3951ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 3952ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia 39533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 39543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 39553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 3956ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } else if (chunk_size == 0) { 3957ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia break; 39583f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 39593f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 39603f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3986ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3987ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3988ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3989ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3990ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3991ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3992ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3993ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3994ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3995ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3996ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3997ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3998ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3999ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 4000ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 4001ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4002ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4003ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 4004ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 4005ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 4006ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 4007ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 4008ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 4009ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4010ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 401105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 401205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 401305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 401405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 401505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 401984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 402084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 4021ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 4022ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 4023ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 4024ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 4025ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 4026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 4027ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4028ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4030ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 4031ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 4032ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4033ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 4034ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4035ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 4036ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 4037ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4038ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4039ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 4040ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4041ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 4042ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 4043ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 4044ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 4045ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4046ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 4047ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 4048ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 4049ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 4050ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4051ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 4052ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 4053ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4054ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4055ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 4056ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 4057ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 4058ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4059ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 4060ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 4061ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4062ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 4063ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 4064ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 4065ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 406648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 4067ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 4068ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 406948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 407048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 407148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 407248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 4073ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 4074b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen uint8_t * newPtr = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 4075b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen if (newPtr == NULL) { 4076b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoAllocSize, smplcnt); 4077b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen return NO_MEMORY; 4078b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen } 4079b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen mCurrentSampleInfoSizes = newPtr; 4080ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 4081ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4082ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4083ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 4084ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 4085ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 4086ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 408784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 408884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 4089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 4090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 4091ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 4092ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 4093ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 4096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 4098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 4099ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4100ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4101ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 4102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 4104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 4105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4107ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 4108c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount == 0) { 4109c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 4110c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 4111c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount > UINT32_MAX / 8) { 4112c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return ERROR_MALFORMED; 4113c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 4114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4115ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 4116c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8); 4117c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (newPtr == NULL) { 4118b6f77710f3355f256c831f2465a21a745e8f9a32Marco Nelissen ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoOffsetsAllocSize, entrycount * 8); 4119c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return NO_MEMORY; 4120c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 4121c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia mCurrentSampleInfoOffsets = newPtr; 4122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 4123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 4125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4126c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (mCurrentSampleInfoOffsets == NULL) { 4127c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 4128c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 4129c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia 4130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 4131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 4132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 4133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 4134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 4137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 4138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 4139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 4140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 4141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 4144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 4145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 4149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 4151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 4153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 4154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 415548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 4156529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen // only 0, 8 and 16 byte initialization vectors are supported 4157529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (ivlength != 0 && ivlength != 8 && ivlength != 16) { 4158529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("unsupported IV length: %d", ivlength); 4159529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen return ERROR_MALFORMED; 4160529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 416148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 4162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 4163529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (i >= mCurrentSamples.size()) { 4164529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("too few samples"); 4165529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen break; 4166529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 4167ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 4168ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4169ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 4170ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 4171ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4172ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4173ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4174ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 4175ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 417648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 417748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 417848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 4179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 418048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 418148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 418248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 4183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 4184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 418648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 418748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 418848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 418948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 419048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 419148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 419248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 419348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 419448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 419548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 419648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 419748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 419848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 4199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 420048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 420148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 420248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 4203ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 4205ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4206ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 4207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 4208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 4209ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 421005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 421105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 421205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 421305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 421405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 421505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 421605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 4217ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 421805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 421905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 422005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 422105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 422205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 422305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 422405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 422505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 422605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 422705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 422805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 422905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 423005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 423105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 423205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 423305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 423405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 423505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 423605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 423705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 423805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 423905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 424005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 424105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 424205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 424305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 424405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 424505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 424605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 424705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 424805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 424905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 425005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 425105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 425205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 425305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 425405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 425505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 425605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 425705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 425805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 425905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 426005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 426105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 426205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 426305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 426405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 426505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 426605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 426705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 426805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 426905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 427105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 427205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 427305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 427405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 427505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 427605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 427705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 427805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 427905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 428005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 428105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 428205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 428305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 428405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 428505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 428605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 428705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 428805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 428905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 429005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 429105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 429205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 429305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 429405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 429505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 429605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 429705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 429805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 429905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 430005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 430105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 430205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 430305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 430405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 430505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 430605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 430705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 430805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 430905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 431005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 431105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 431205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 431305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 431405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 431505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 431605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 431705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 431805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 431905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 432005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 432105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 432205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 432305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 432405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 432505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 432605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 432705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 432805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 432944a9bf5b013641a55d1784da353461e7446ff756Wei Jia // |version| only affects SampleCompositionTimeOffset field. 433044a9bf5b013641a55d1784da353461e7446ff756Wei Jia // If version == 0, SampleCompositionTimeOffset is uint32_t; 433144a9bf5b013641a55d1784da353461e7446ff756Wei Jia // Otherwise, SampleCompositionTimeOffset is int32_t. 433244a9bf5b013641a55d1784da353461e7446ff756Wei Jia // Sample.compositionOffset is defined as int32_t. 433344a9bf5b013641a55d1784da353461e7446ff756Wei Jia uint8_t version = flags >> 24; 433444a9bf5b013641a55d1784da353461e7446ff756Wei Jia flags &= 0xffffff; 433544a9bf5b013641a55d1784da353461e7446ff756Wei Jia ALOGV("fragment run version: 0x%02x, flags: 0x%06x", version, flags); 433605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 433705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 433805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 433905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 434005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 434105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 434205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 434305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 434405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 434505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 434605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 434705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 434805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 434905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 435005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 435105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 435205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 435305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 435405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 435505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 435605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 435705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 435805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 435905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 436005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 436105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 436205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 436305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 436405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 436505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 436605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 436705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 436805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 436905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 437005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 437105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 437205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 437305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 437405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 437505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 437605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 437705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 437805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 437905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 438005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 438105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 438205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 438305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 438405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 438505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 438605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 438705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 438805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 438905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 4390c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 4391c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 439205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 439305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 439405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 439505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 439605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 439705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 439805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 439905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 440005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 440105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 440205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 440305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 440405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 440505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 440605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 440705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 440805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 440905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 441005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 441105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 441205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 441305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 441405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 441505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 441605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 441705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4418ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar if (size < (off64_t)(sampleCount * bytesPerSample)) { 441905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 442005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 442105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 442205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 442305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 442405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 442505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 442605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 442705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 442805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 442905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 443005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 443105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 443205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 443305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 443405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 443505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 443605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 443705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 443805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 443905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 444005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 444105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 444305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 444505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 444605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 444705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 444805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 444905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 445005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 445105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4452a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 4453ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 445405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 445505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 445605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 445705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 445805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 445905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 4460c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 446105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 446205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 446305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 446405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 446505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 446605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 446705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 446805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 446905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 447005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 447120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 44727b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 44737b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 447420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 447520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 447620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 44786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 44796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 44806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 44816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 44826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 44836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 44846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 44856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 44866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 44876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 44886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 44896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 44906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 44916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 44926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 44936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 44946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 44956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 449620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 449720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 44987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 44997b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 4500dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 450120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4502cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) { 4503cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung *out = nullptr; 4504cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung return WOULD_BLOCK; 4505cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung } 4506cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung 450705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 450805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 450905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 451005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 451120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 451220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4513abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 4514abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 451520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 4516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 4517abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 4518abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 4519abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 4520abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 4521abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4522abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4523abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 4524abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 4525abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4526abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 4527abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 4528abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 4529abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4530abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 4531abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 4532abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4534abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 453520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 4536abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 4537599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 4538abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 4539abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4540abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4541abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 4542abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 4543abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 4544abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4545abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4546abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4547abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 4548abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 4549abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 4550abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 4551abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 455220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4553788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 4554788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 4555788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 4556788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 4557788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 4558788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 455920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 45605295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 45615295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 45625295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 45635295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 45645295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 45655295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 45665295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 45675295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 456805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 456920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 457020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 457120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4572abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4573abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 4574abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4575abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4576abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 4577abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 4578abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 4579abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 4580abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4581df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 4582abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 4583abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 4584abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 4585abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 4586abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 4587abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4588abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 458920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 459020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 459120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 459220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 459320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 459420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 459520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 459620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 459765c954e72a126e4ea59d1fe2859bfb39cb800380Caroline Tice off64_t offset = 0; 459865c954e72a126e4ea59d1fe2859bfb39cb800380Caroline Tice size_t size = 0; 4599170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 46008bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 4601dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 4602dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 4603dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 460420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4605c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 4606c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 4607170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 460820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4609dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4610dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4611dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4612dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4613dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 4614c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 4615dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4616ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 4617dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4618dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4619c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4620c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4621c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4622c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 46230024245e134467d120b40099da16c467dc365e76Andreas Huber } 462420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 4626dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 4627dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 462834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 4629dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4630dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 4631dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4632dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4633dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4634dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 4635dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4636dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 46377b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4638dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 4639dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 464048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 46414678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4642170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4643170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4644abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4645abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4646abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4647abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4648abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4649abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 46508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 46518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 46528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 46538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4654dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 4655dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4656dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 46573b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 4658dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 4659dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4660dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4661dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4662dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4663dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4664dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 4665dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 4666dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 46676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 4668dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4669dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 4670dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 4671dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 46726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 46735d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 46745d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 46755d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 46765d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 467729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 4678e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4679e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 4680e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 4681e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4682e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 4683e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 4684dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4685dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 46867b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 46876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 4688dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 46897b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4690dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 46916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 46926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 4693dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4694dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 4695dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4696dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4697dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4698dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4699dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 4700dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4701dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4702dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 4703dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 4704dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 4705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 4706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 4707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 4710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 4711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 4713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 471420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 471520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 471620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 471720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 471820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4719dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 472020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 472120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 47256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 4726dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4727dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 4728dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 4729dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 4730e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4731dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 4732bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 473334fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 473434fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 473534fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 473634fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 4737bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength); 473834fe252c89e33572d01fea981b58d7b115e76164James Dong } 4739e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 474034fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 474129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 4742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 4743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 4744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 4745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 4747dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 4748dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 4749dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4750dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 475187afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 475287afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 475387afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 475487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size()); 475587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen android_errorWriteLog(0x534e4554, "27208621"); 475687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer->release(); 475787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer = NULL; 475887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen return ERROR_MALFORMED; 475987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen } 4760dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4761dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4762dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4763dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4764dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 4765dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 4766dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 4767dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 4768dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4769dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 4770dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4771dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 4772dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4773dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 477420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 477548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 47764678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4777170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4778170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4779abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4780abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4781abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4782abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4783abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4784abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 47854dbff11975e737482537e1636051690188f3fbc4Praveen Chavan if (mIsAVC) { 47864dbff11975e737482537e1636051690188f3fbc4Praveen Chavan uint32_t layerId = FindAVCLayerId( 47874dbff11975e737482537e1636051690188f3fbc4Praveen Chavan (const uint8_t *)mBuffer->data(), mBuffer->range_length()); 47884dbff11975e737482537e1636051690188f3fbc4Praveen Chavan mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId); 47894dbff11975e737482537e1636051690188f3fbc4Praveen Chavan } 47904dbff11975e737482537e1636051690188f3fbc4Praveen Chavan 47918bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 47928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 47938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 47948bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 479520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 479620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 479720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 479820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 479920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 480020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 480120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 480220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 480320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 480405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 480505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 480605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 480705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 480805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 480905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 481005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 481105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 481205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 481305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 481405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 481505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 481605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 481705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 481805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 481905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 482005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 482105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 482205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 482305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 482405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 482505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 482605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 48273f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 482805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 482905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 483005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 483105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 483205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 483305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 483405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 483505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 483605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 483705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 483805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 483905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4840ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 4841ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia mNextMoofOffset = -1; 4842ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4843ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4844ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia status_t err = parseChunk(&totalOffset); 4845ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (err != OK) { 4846ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return err; 4847ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 4848ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 4849ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 4850ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 4851ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 4852ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia mNextMoofOffset = -1; 4853ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4854ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4855ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 4856ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia status_t err = parseChunk(&tmp); 4857ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (err != OK) { 4858ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return err; 4859ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 4860ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 486105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 486205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 486305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 486405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 486505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 486605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 486705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 486805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 486905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 487005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 487105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4872442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 487305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 487405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 487505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 487605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 487705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 487805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 487905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 48803f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 48813f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 48823f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 48833f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4884ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 488505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 488605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 488705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 4888ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia status_t err = parseChunk(&nextMoof); 4889ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia if (err != OK) { 4890ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia return err; 4891ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381aWei Jia } 4892ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4893ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4894ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 489505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 489605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 489705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 489805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 489905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4900c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 490105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 490205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 490305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 490405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 490505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 490605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 490705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 490805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 490905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 491005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4911c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4912c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4913c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4914c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 491505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 491605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 491748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 491848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 491948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 492048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 492148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 492248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 492348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 492448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 492548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 492648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 492748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 492848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 492948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 493048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 493148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 49323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 493305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 4934da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (!isInRange((size_t)0u, mBuffer->size(), size)) { 4935da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4936da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4937da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 4938da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size); 4939da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4940da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4941da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 494205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 494305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 494405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 494505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 494605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 494705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 494805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4949da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 495005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 495105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 495205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 495305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 495405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 495505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 495605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4957170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4958170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 495905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 496005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 496105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 496205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 496305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 496405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 49654dbff11975e737482537e1636051690188f3fbc4Praveen Chavan if (mIsAVC) { 49664dbff11975e737482537e1636051690188f3fbc4Praveen Chavan uint32_t layerId = FindAVCLayerId( 49674dbff11975e737482537e1636051690188f3fbc4Praveen Chavan (const uint8_t *)mBuffer->data(), mBuffer->range_length()); 49684dbff11975e737482537e1636051690188f3fbc4Praveen Chavan mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId); 49694dbff11975e737482537e1636051690188f3fbc4Praveen Chavan } 49704dbff11975e737482537e1636051690188f3fbc4Praveen Chavan 497105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 497205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 497305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 497405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 497505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 497605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 497705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 49783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 497905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 498005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 498105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 498205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 498305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 498405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 498505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 498605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 498705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 498805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 498905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 499005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 499105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 499205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 499305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 49945d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 49955d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 49965d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 49975d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen 49985d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 499905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 500005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 500105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 500205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 500305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 500405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 500505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 500605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 500705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 500805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 500905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 501005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 501105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 501205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 501305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 501405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 501505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 501605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 501705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 501805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 501905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 502005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 502105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 502205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 502305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 502405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 502505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 502605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 502705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 502805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 502905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 503005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 5031da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih void *data = NULL; 5032da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih bool isMalFormed = false; 503305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 5034da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) { 5035da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 5036da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 5037da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mBuffer->data(); 5038da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 503905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 5040da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih int32_t max_size; 5041da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mFormat == NULL 5042da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !mFormat->findInt32(kKeyMaxInputSize, &max_size) 5043da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, (size_t)max_size, size)) { 5044da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 5045da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 5046da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mSrcBuffer; 5047da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 504805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 504905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 5050da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (isMalFormed || data == NULL) { 5051da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("isMalFormed size %zu", size); 5052da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer != NULL) { 5053da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 5054da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 5055da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 5056da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 5057da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 5058da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih num_bytes_read = mDataSource->readAt(offset, data, size); 5059da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 506005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 506105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 506205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 506305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 5064da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 506505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 506605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 506705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 506805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 506905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 507005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 507105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 507205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 507305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 507405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 507505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 507605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 507705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 5078da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 507905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 508005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 508105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 508205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 5083da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength) 5084da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u) 5085da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength); 508605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 508705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 508805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 5089da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("Video is malformed; nalLength %zu", nalLength); 509005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 509105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 509205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 509305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 509405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 509505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 509605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 509705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 509805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 50995403587a74aee2fb57076528c3927851531c8afbMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 51005403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 51015403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 51025403587a74aee2fb57076528c3927851531c8afbMarco Nelissen ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size()); 51035403587a74aee2fb57076528c3927851531c8afbMarco Nelissen android_errorWriteLog(0x534e4554, "26365349"); 51045403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer->release(); 51055403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer = NULL; 51065403587a74aee2fb57076528c3927851531c8afbMarco Nelissen return ERROR_MALFORMED; 51075403587a74aee2fb57076528c3927851531c8afbMarco Nelissen } 510805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 510905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 511005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 511105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 511205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 511305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 511405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 511505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 511605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 511705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 511805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 511905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 512005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 512105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 512205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 512305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 5124170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 5125170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 512605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 512705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 512805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 512905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 513005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 513105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 513205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 513305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 513405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 513505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 513605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 513705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 513805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 513905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 514005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 514105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 514205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 514305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 514405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 5145bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 5146bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 5147bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 5148bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 5149bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 5150bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 5151bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 5152bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 5153bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 5154bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 5155bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 5156bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 5157bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 5158bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 5159ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essickvoid MPEG4Extractor::populateMetrics() { 5160ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick ALOGV("MPEG4Extractor::populateMetrics"); 5161ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick} 5162ba13b7bc3d46d958bc4a395f2c162cb112ec1f3aRay Essick 51631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 5164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 516520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 516620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 516734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 516820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 516920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 517020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 517120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 517220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 5173b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 5174b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 51750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 5176ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 5177983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 517818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 51795a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 518020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 518120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 518220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 518320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 518420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 518520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 518620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 51881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 51891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 51901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 51911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 51923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 51933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 51941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 51951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 51961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 51974cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 51984cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 51994cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 52004cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 52014cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 520258fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 520358fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 520458fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 52051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 52061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 52071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 52081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 52091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 52101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 52111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 52121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 52131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 52141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 52151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 52161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 52171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 52181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 52191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 5220a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 5221a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 5222a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 52231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 5224a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 5225a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 5226a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 5227a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 52281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 5229a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 5230a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 5231a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 5232a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 52331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 5234a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 5235a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 5236a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 5237a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 5238a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5239a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5240a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 5241a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 5242a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 5243a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5244a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 5245a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 52461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 52471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 52481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 5249a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 5250a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 5251a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5252a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 5253a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 5254a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 5255a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5256452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 5257a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 5258a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 5259a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 5260a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5261a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5262452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - offset) is either 8 or 16 5263452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset); 5264452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunkDataSize < 0) { 5265452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 5266452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 5267452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 5268a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 526905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 527005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 5271ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset); 5272a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 5273a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 5274a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 5275a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 5276a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 5277a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5278a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5279a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 5280a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 5281a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 5282a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 5283a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 5284a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 5285a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5286a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5287a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 5288a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 5289a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 5290a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 5291a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5292a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5293a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 5294a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5295a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 5296a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 5297a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 5298a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5299a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5300a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5301a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 5302a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 5303a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5304a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 53051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 53061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 5307a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5308a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 5309a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 5310a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 5311a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5312a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 5313a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 5314a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5315a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5316a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 5317a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 53181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 5319a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5320a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 53211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 53221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 5323a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 53241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 53251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 53261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 53271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 53285a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 53291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 5330a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 5331a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 5332a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 5333a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 5334ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset); 5335a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 5336a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 53371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 53381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 53391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 53401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 53415a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 5342a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 5343a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 53441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 53451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 53461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 53471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 53485ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 53491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 53501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 53511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 53521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 53531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 53541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 535520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 5356