120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen//#define LOG_NDEBUG 0 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1989e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <utils/Log.h> 27a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 28a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/MPEG4Extractor.h" 29a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/SampleTable.h" 30a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include "include/ESDS.h" 31a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ABitReader.h> 33d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson#include <media/stagefright/foundation/ABuffer.h> 34ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 35a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 36bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 3758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar#include <media/stagefright/foundation/ColorUtils.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 4018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé#include <byteswap.h> 46328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé#include "include/ID3.h" 47fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 48937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#ifndef UINT32_MAX 49937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#define UINT32_MAX (4294967295U) 50937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia#endif 51937c6bedd4b6e5c6cb29a238eb459047dedd3486Wei Jia 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 540dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnarenum { 550dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar // max track header chunk to return 560dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar kMaxTrackHeaderSize = 32, 570dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar}; 580dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 62942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen MPEG4Source(const sp<MPEG4Extractor> &owner, 63942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MetaData> &format, 64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 6548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 6605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 6705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 68c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 6905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset); 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 7705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 80693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 81693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 837b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 847b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 85942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen // keep the MPEG4Extractor around, since we're referencing its data 86942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen sp<MPEG4Extractor> mOwner; 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 88693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 90693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 9205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentFragmentIndex; 9305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &mSegments; 94c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *mTrex; 9505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mFirstMoofOffset; 9605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mCurrentMoofOffset; 9705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t mNextMoofOffset; 9805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mCurrentTime; 9905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mLastParsedTrackId; 10005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t mTrackId; 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mCryptoMode; // passed in from extractor 103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int32_t mDefaultIVSize; // passed in from extractor 104ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t mCryptoKey[16]; // passed in from extractor 105ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoType; 106ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentAuxInfoTypeParameter; 10748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t mCurrentDefaultSampleInfoSize; 108ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoCount; 109ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoAllocSize; 110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t* mCurrentSampleInfoSizes; 111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetCount; 112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t mCurrentSampleInfoOffsetsAllocSize; 113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t* mCurrentSampleInfoOffsets; 114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 1163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar bool mIsHEVC; 1176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 1186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1270024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 1280024245e134467d120b40099da16c467dc365e76Andreas Huber 1296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 13005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseChunk(off64_t *offset); 13105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 13205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t parseTrackFragmentRun(off64_t offset, off64_t size); 133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 13505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 13605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct TrackFragmentHeaderInfo { 13705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum Flags { 13805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kBaseDataOffsetPresent = 0x01, 13905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDescriptionIndexPresent = 0x02, 14005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleDurationPresent = 0x08, 14105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleSizePresent = 0x10, 14205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDefaultSampleFlagsPresent = 0x20, 14305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDurationIsEmpty = 0x10000, 14405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 14505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 14605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mTrackID; 14705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mFlags; 14805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mBaseDataOffset; 14905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mSampleDescriptionIndex; 15005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleDuration; 15105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleSize; 15205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t mDefaultSampleFlags; 15305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 15405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t mDataOffset; 15505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 15605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 15705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 15805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen struct Sample { 15905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset; 16005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t size; 16105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration; 162c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t compositionOffset; 163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t iv[16]; 164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> clearsizes; 165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Vector<size_t> encryptedsizes; 16605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 16705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<Sample> mCurrentSamples; 1686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 184c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 185c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 188c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 197c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 19850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 19950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 20050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 20250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 20450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 20550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 20650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 20750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 20850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 20950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 21050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 21150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 21250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 21550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 21650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 21750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 21850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 21950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 22050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 22150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 22250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 22350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 22550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 22650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 22750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 22850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 22950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 23050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 23150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 232c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 23350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 23450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 235bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar if (isInRange(mCachedOffset, mCachedSize, offset, size)) { 23650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 23750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 23850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 23950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 24150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 243c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 24450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 24550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 24650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 24750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 24850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 24950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 25050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 251c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 25250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 25350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 25550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 25750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 25850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 25950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 26050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 26150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 26350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 26450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 26650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 26750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 26850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 26950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 27150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 27250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 27450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 27550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 27650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 27750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 278b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampestatic const bool kUseHexDump = false; 279b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 284377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("0x%04zx ", offset); 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 32218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 32518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 327371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 32818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 329371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 33118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 334e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 335e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 33618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 33918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 3423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 3433b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return MEDIA_MIMETYPE_VIDEO_HEVC; 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 345dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 35148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 35248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR NB audio is always mono, 8kHz 35348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 35448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 8000; 35548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 35648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 35748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // AMR WB audio is always mono, 16kHz 35848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *channels = 1; 35948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen *rate = 16000; 36048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return true; 36148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 36248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return false; 36348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 36448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 365693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 366c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen : mMoofOffset(0), 367928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound(false), 368928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound(false), 36905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource(source), 370bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 3717be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 372fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale(0), 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 37472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 375dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 376dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 377dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 3938da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen delete[] sinf->IPMPData; 394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 398ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 399ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 400ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen delete [] mPssh[i].data; 401ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenuint32_t MPEG4Extractor::flags() const { 40505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return CAN_PAUSE | 40605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 40705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 40805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 40905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 4117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 4127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 41372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 4147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 4157be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 41672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 4177be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 4187be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 422ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Extractor::countTracks: no tracks"); 423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 433a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("MPEG4Extractor::countTracks: %zu tracks", n); 434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 4387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 454371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 455371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 456371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 457371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 4587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 4597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 4607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 4617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 4627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 4637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 4647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 46505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mMoofOffset > 0) { 46605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration; 46705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->meta->findInt64(kKeyDuration, &duration)) { 46805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // nothing fancy, just pick a frame near 1/4th of the duration 46905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 47005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, duration / 4); 47105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 47205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 47305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleIndex; 47405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleTime; 47505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 47605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen && track->sampleTable->getMetaDataForSample( 47705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleIndex, NULL /* offset */, NULL /* size */, 47805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen &sampleTime) == OK) { 47905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta->setInt64( 48005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyThumbnailTime, 48105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ((int64_t)sampleTime * 1000000) / track->timescale); 48205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 4840dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 4850dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar // MPEG2 tracks do not provide CSD, so read the stream header 4860dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) { 4870dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar off64_t offset; 4880dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar size_t size; 4890dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (track->sampleTable->getMetaDataForSample( 4900dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) { 4910dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (size > kMaxTrackHeaderSize) { 4920dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar size = kMaxTrackHeaderSize; 4930dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 4940dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar uint8_t header[kMaxTrackHeaderSize]; 4950dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) { 4960dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar track->meta->setData(kKeyStreamHeader, 'mdat', header, size); 4970dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 4980dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 4990dc8be97f0fbee707b69b24b3a8d914f88c77423Lajos Molnar } 5007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5017e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) { 50748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[0] = x >> 24; 50848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[1] = (x >> 16) & 0xff; 50948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[2] = (x >> 8) & 0xff; 51048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[3] = x & 0xff; 51148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen s[4] = '\0'; 51248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen} 51348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 515bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 516bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 519c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 521928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang bool sawMoovOrSidx = false; 522928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 523928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) { 524a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t orig_offset = offset; 52505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen err = parseChunk(&offset, 0); 526a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen 5274ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar if (err != OK && err != UNKNOWN_ERROR) { 5284ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar break; 5294ff2a0dbb178c4ea652f30aa4f1d3deb9fdbc832Lajos Molnar } else if (offset <= orig_offset) { 530a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // only continue parsing if the offset was advanced, 531a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // otherwise we might end up in an infinite loop 532ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset); 533a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen err = ERROR_MALFORMED; 534a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen break; 535928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } else if (err == UNKNOWN_ERROR) { 536928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang sawMoovOrSidx = true; 53705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5397be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 540bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 54172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 542bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber mFileMetaData->setCString( 543bc8b5faec8a0a9ad7c8d94945e7b000d63f0afe6Andreas Huber kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 54472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 54572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 54672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 547bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 548bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 551bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 552ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 553ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // copy pssh data into file metadata 554c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen uint64_t psshsize = 0; 555ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 556ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen psshsize += 20 + mPssh[i].datalen; 557ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 558c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (psshsize > 0 && psshsize <= UINT32_MAX) { 559ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *buf = (char*)malloc(psshsize); 5606a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (!buf) { 5616a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 5626a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 5636a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 564ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char *ptr = buf; 565ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mPssh.size(); i++) { 566ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 567ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 568ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ptr += (20 + mPssh[i].datalen); 569ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 570ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 571ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(buf); 572ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 573bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 576dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 577dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 578dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 579dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 580dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 581dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 582dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 583dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 584dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 585dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 586dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 587dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 588dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 589dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 590dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 591dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 592dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 593dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 594dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 59556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic int32_t readSize(off64_t offset, 596dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 597dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 598dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 599dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 600dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 601dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 602dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 603dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 604dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 605dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 606dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 607dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 608dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 609dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 610dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 611dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 612dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 613dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 614dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 61584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Extractor::parseDrmSINF( 61684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t * /* offset */, off64_t data_offset) { 617dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 618dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 619dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 620dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 621dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 622dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 623dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 624dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 625dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 626dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 627dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 628dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 629dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 630dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 631dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 632dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 633dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 634dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 635dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 636dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 637dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 638dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 639dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 640dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 641dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 642dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 643dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 644dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 645dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 646dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 647dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 648dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 649dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 650dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 651dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 652dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 653dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 654dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 655dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 656dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 657dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 658dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 659dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 660dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 661dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 662dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 663dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 664dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 665dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 666dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 667dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 668dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 669dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 670dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 671dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 672dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 673dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 674dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 675dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 676dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 677dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 678dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 679dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 680dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 681dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 682dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 683dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 684dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 685dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 686dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 687dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 688dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 689dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 690dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 691dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 692dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 693dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 694dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 695dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 696dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 697dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 698dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 699dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 700dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 701dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 702dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 703dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 704dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 705dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 706dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 707dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 708dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 709dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 710dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 711dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 712dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 713dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 714dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 715dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 716dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 717dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 718dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 719dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 720dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 721dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 722dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 723dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 724dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 7258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen sinf->IPMPData = new (std::nothrow) char[sinf->len]; 7268da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (sinf->IPMPData == NULL) { 7278da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 7288da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 729f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara data_offset += 2; 730dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 731f7df9ab3187a3c02bffe1fba10d3fb95197e4a07Ichitaro Kohara if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 732dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 733dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 734dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 735dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 736dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 737dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 738dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 739dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 740dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 741dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 742dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 743dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 744dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 745dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 746dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 74772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 74872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 74972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 75072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 75172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 75272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 75472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 75572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 75672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 75772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 75872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 75972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 76172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 76272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 76372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 76472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 76572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 76672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 76772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 76872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 76972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 77072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 77172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 7728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatic bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) { 7738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return path.size() >= 2 7748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[0] == FOURCC('m', 'o', 'o', 'v') 7758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && path[1] == FOURCC('m', 'e', 't', 'a') 7768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang && (depth == 2 7778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || (depth == 3 778ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang && (path[2] == FOURCC('h', 'd', 'l', 'r') 779ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang || path[2] == FOURCC('i', 'l', 's', 't') 7808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || path[2] == FOURCC('k', 'e', 'y', 's')))); 7818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 7828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 78372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 7843724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissenstatic bool convertTimeToDate(int64_t time_1904, String8 *s) { 7853724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen // delta between mpeg4 time and unix epoch time 7863724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen static const int64_t delta = (((66 * 365 + 17) * 24) * 3600); 7873724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (time_1904 < INT64_MIN + delta) { 7883724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return false; 7893724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 7903724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen time_t time_1970 = time_1904 - delta; 79172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 79272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 7933724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen struct tm* tm = gmtime(&time_1970); 7943724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (tm != NULL && 7953724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) { 7963724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen s->setTo(tmp); 7973724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return true; 7983724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 7993724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen return false; 80072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 80172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 802c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 803ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth); 804452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 805452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (*offset < 0) { 806452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 807452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 808452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 81034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 8142d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer int32_t chunk_type = ntohl(hdr[1]); 815c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 81834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 82371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 82471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 82571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 82671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 82771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 828a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else if (chunk_size == 0) { 829a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (depth == 0) { 830a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // atom extends to end of file 831a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen off64_t sourceSize; 832a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen if (mDataSource->getSize(&sourceSize) == OK) { 833a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen chunk_size = (sourceSize - *offset); 834a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 835a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // XXX could we just pick a "sufficiently large" value here? 836a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen ALOGE("atom size is 0, and data source has no size"); 837a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return ERROR_MALFORMED; 838a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 839a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } else { 840a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen // not allowed for non-toplevel atoms, skip it 841a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen *offset += 4; 842a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen return OK; 843a91b538853e94191fbceab5f5050940dd6b96577Marco Nelissen } 84471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 84571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 846a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("invalid chunk size: %" PRIu64, chunk_size); 84771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 852ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth); 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 854b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 855b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe static const char kWhitespace[] = " "; 856b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 857b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size); 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 859b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe char buffer[256]; 860b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t n = chunk_size; 861b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (n > sizeof(buffer)) { 862b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe n = sizeof(buffer); 863b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 864b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (mDataSource->readAt(*offset, buffer, n) 865b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe < (ssize_t)n) { 866b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return ERROR_IO; 867b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 868ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 869b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(buffer, n); 870b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 87372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 874452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - *offset) is either 8 or 16 875452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunk_data_size = chunk_size - (data_offset - *offset); 876452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunk_data_size < 0) { 877452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 878452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 879452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 882515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 88372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 884c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 88572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 88672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 88772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 88872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 88972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 89072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 89172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 892bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 893bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 894bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 895bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 89672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 89772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 89872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 89972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 91172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 91272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 913ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'i', 'n', 'f'): 914ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'c', 'h', 'i'): 9150a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'd', 't', 's'): 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 917928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang if (chunk_type == FOURCC('m', 'o', 'o', 'f') && !mMoofFound) { 918928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang // store the offset of the first segment 919928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofFound = true; 920928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMoofOffset = *offset; 921928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang } 922928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 92350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 924a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size); 92550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 926b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 927b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 928b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 92950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 93050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 93150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 93250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 93350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 93450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 93550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 9361edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 937f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 938f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 939f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 9401edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 94150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 94250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 944bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 9456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 9466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 947bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 948bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 949bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 950bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 951bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 952bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 953bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 954bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 955bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 956bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 957bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 9586f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 959bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 960bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 961bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 962bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 963c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 972bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 973bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 974bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 975bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 9766f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 9770386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia int32_t trackId; 9780386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia // There must be exact one track header per track. 9790386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 9800386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia mLastTrack->skipTrack = true; 9810386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } 9826f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 9836f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 9846f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9856f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 9866f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 9876f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 9886f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 9896f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 9906f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 9916f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9926f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 9936f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 9946f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 9956f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9966f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 9976f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 9986f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 9996f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 1000bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 1001bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1002bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 1003bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 1004bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1005bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 1006bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1008dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1009dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 1010dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1011dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 1012dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10170a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen case FOURCC('e', 'l', 's', 't'): 10180a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen { 10190517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10200517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 10210a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // See 14496-12 8.6.6 10220a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint8_t version; 10230a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mDataSource->readAt(data_offset, &version, 1) < 1) { 10240a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10250a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10260a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10270a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t entry_count; 10280a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 10290a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10300a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10310a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10320a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (entry_count != 1) { 10330a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen // we only support a single entry at the moment, for gapless playback 10340a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen ALOGW("ignoring edit list with %d entries", entry_count); 1035fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen } else if (mHeaderTimescale == 0) { 1036210efd48ed21ca0084d9440f9a1db7d9878f8094Marco Nelissen ALOGW("ignoring edit list because timescale is 0"); 10370a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10380a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen off64_t entriesoffset = data_offset + 8; 10390a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint64_t segment_duration; 10400a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t media_time; 10410a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10420a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (version == 1) { 10430a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 10440a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 10450a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10460a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10470a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else if (version == 0) { 10480a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen uint32_t sd; 10490a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t mt; 10500a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (!mDataSource->getUInt32(entriesoffset, &sd) || 10510a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 10520a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10530a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10540a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen segment_duration = sd; 10550a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen media_time = mt; 10560a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } else { 10570a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen return ERROR_IO; 10580a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10590a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1060fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t halfscale = mHeaderTimescale / 2; 1061fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 1062fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 10630a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10640a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t duration; 10650a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int32_t samplerate; 10661391f933b49cfb56da9aa63f723de83b076cf888Robert Shih if (!mLastTrack) { 10671391f933b49cfb56da9aa63f723de83b076cf888Robert Shih return ERROR_MALFORMED; 10681391f933b49cfb56da9aa63f723de83b076cf888Robert Shih } 10690a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 10700a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 10710a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 10720a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t delay = (media_time * samplerate + 500000) / 1000000; 10730a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 10740a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1075608fe1d6b2ea4d88245a109afe2bfba580881a16Wei Jia int64_t paddingus = duration - (int64_t)(segment_duration + media_time); 1076465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen if (paddingus < 0) { 1077465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // track duration from media header (which is what kKeyDuration is) might 1078465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // be slightly shorter than the segment duration, which would make the 1079465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen // padding negative. Clamp to zero. 1080465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen paddingus = 0; 1081465127fa3dfba81d8ad2a164ba6036478f71c8a6Marco Nelissen } 10820a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 10830a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 10840a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10850a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10860a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen break; 10870a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen } 10880a69bd281c76bf777ddb51d0c6c08519634b192dMarco Nelissen 1089ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('f', 'r', 'm', 'a'): 1090ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 10910517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 10920517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 109348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t original_fourcc; 1094ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 1095ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1096ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1097ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen original_fourcc = ntohl(original_fourcc); 1098ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("read original format: %d", original_fourcc); 1099f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1100f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1101f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1102f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1103ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 110448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = 0; 110548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t sample_rate = 0; 110648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 110748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 110848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 110948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 1110ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1111ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1112ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1113ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('t', 'e', 'n', 'c'): 1114ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1117ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_size < 32) { 1118ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1119ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1120ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1121ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1122ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // default IV size, 16 bytes default KeyID 1123ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // (ISO 23001-7) 1124ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen char buf[4]; 1125ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1126ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1127ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1128ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1129ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1130ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (defaultAlgorithmId > 1) { 1131ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only 0 (clear) and 1 (AES-128) are valid 1132ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1133ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1134ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1135ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(buf, 0, 4); 1136ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1137ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1138ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1139ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1141ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1142ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1143ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only unencrypted data must have 0 IV size 1144ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1145ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else if (defaultIVSize != 0 && 1146ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 8 && 1147ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen defaultIVSize != 16) { 1148ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // only supported sizes are 0, 8 and 16 1149ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1150ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1151ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1152ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defaultKeyId[16]; 1153ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1154ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1155ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1156ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1157ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1158f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1159f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1160f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1161ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1162ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1163ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1164ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1165ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1166ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 116720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 11690517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11700517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1171ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 1172ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1173ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 117520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 117720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1179ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('p', 's', 's', 'h'): 1180ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen { 11810517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 11820517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1183ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen PsshInfo pssh; 1184ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1185ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1186ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1187ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1188ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1189ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t psshdatalen = 0; 1190ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1191ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1192ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1193ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen pssh.datalen = ntohl(psshdatalen); 1194ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("pssh data size: %d", pssh.datalen); 1195c9b255b7f771f55462cadd34e109bfee3bf80a3aMarco Nelissen if (chunk_size < 20 || pssh.datalen > chunk_size - 20) { 1196ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // pssh data length exceeds size of containing box 1197ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 1198ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1199ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 12008da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen pssh.data = new (std::nothrow) uint8_t[pssh.datalen]; 12018da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (pssh.data == NULL) { 12028da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 12038da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 1204ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("allocated pssh @ %p", pssh.data); 1205ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ssize_t requested = (ssize_t) pssh.datalen; 1206ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1207ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 1208ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1209ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mPssh.push_back(pssh); 1210ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 1211ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 1212ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 1213ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 12160517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 12170517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1218202fbed96db40ec5fb43d633fc97601a15a6dd7aRobert Shih if (chunk_data_size < 4 || mLastTrack == NULL) { 121920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 122020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 122120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 122220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 122334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1229c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 124034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12462e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (!timescale) { 12472e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale should not be ZERO."); 12482e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 12492e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 12502e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1253c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 14496-12 says all ones means indeterminate, but some files seem to use 1254c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 0 instead. We treat both the same. 125505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t duration = 0; 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 125734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1262c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration != -1) { 1263c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = ntoh64(duration); 1264c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 126520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 126605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t duration32; 126734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 126820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (duration32 != 0xffffffff) { 127305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen duration = ntohl(duration32); 127405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1276e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mLastTrack->timescale != 0) { 1277c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64( 1278c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1279c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 12827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 12837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 12847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 12857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 12867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 12877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 12887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 12927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 12937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 12947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 12957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 12967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 12977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 12987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 12997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 13007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 13017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 13027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 13037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 13047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 13067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 13077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 130920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 131020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 131120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 131320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 131420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 131520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 131620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 131720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 1318c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1319bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1320bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1321bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 132234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 132320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 132420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 132520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 132620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 132720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 132820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 132920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 133020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 133120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 133320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 13353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 13363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 13373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 1338ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // For encrypted files, there may also be more than one entry. 13393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 1340f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1341f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1342f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1343f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 13443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1345ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1346ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen strcasecmp(mime, "application/octet-stream")) { 13473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 13483b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 13493b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 13503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 13513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1353c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1361bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1362bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1363bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1364bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 136620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 136948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen case FOURCC('e', 'n', 'c', 'a'): 137020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1371371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 137220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 137320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 137420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 137520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 137620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 137720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 137820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 137934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 138020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 138220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1384b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 138548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t num_channels = U16_AT(&buffer[16]); 138620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 138781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 138881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 138981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1390f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1391f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1392f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 139348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 139448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // if the chunk type is enca, we'll get the type from the sinf/frma box later 139548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 139648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 139848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 139981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 140120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1403c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 140620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 141020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1411bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1412bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1413bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1414bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 141620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 141820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1419ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('e', 'n', 'c', 'v'): 142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 1421e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 1422e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 14243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', '1'): 14253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'e', 'v', '1'): 142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 14277be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 14287be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 143020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 143220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 143320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 143420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 143534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1440b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint16_t data_ref_index __unused = U16_AT(&buffer[6]); 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1444ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // The video sample is not standard-compliant if it has invalid dimension. 1445a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1446a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1447a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1448a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1449a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1450a6256238d9015c42129fe43791968768fe501efaJames Dong 1451134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1452134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1454f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1455f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1456f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1457ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1458ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if the chunk type is encv, we'll get the type from the sinf/frma box later 1459ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1460ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1464c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 146520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 146620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 146720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 146820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 146920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1472bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1473bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1474bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1475bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 148120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1482274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1483274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1484274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 148520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 148620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 148720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 148820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14890517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 14900517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 149120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 149220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 149320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 149420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 149520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 149720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 149820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1500274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1501274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1502274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 150320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 150620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15070517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15080517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 150920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 151020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 151120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 151420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 151820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1519274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1520274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1521274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 152220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 152520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15260517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 15270517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 153020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 153120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1532738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 153349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 153449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 153549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 153649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 153749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1538738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 153905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (max_size != 0) { 154005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Assume that a given buffer only contains at most 10 chunks, 154105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each chunk originally prefixed with a 2 byte length will 154205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 154305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // and thus will grow by 2 bytes per chunk. 1544beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (max_size > SIZE_MAX - 10 * 2) { 1545beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("max sample size too big: %zu", max_size); 1546beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1547beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 154805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 154905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 155005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // No size was specified. Pick a conservatively large size. 1551beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen uint32_t width, height; 1552beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) || 1553beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) { 155405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("No width or height, assuming worst case 1080p"); 1555f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar width = 1920; 1556f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar height = 1080; 1557beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } else { 1558beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // A resolution was specified, check that it's not too big. The values below 1559beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // were chosen so that the calculations below don't cause overflows, they're 1560beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen // not indicating that resolutions up to 32kx32k are actually supported. 1561beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen if (width > 32768 || height > 32768) { 1562beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen ALOGE("can't support %u x %u video", width, height); 1563beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen return ERROR_MALFORMED; 1564beef7e58c1f1837bdaed6ac37414d8c48a133813Marco Nelissen } 156505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1566f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar 15674256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen const char *mime; 15684256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 156907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) 157007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 157107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar // AVC & HEVC requires compression ratio of at least 2, and uses 1572f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // macroblocks 1573f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1574f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar } else { 1575f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // For all other formats there is no minimum compression 1576f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar // ratio. Use compression ratio of 1. 1577f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar max_size = width * height * 3 / 2; 157805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1579f40cde132d14a260f4f7e08ae2bf29d8c55848aeLajos Molnar mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 158005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 1581113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 15824256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // NOTE: setting another piece of metadata invalidates any pointers (such as the 15834256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen // mimetype) previously obtained, so don't cache them. 1584113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1585113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1586113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1587113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1588113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1589949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (nSamples == 0) { 1590949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t trackId; 1591949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { 1592949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 1593949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen Trex *t = &mTrex.editItemAt(i); 1594949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (t->track_ID == (uint32_t) trackId) { 1595949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (t->default_sample_duration > 0) { 1596949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t frameRate = 1597949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->timescale / t->default_sample_duration; 1598949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1599949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1600949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen break; 1601949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1602949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1603949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1604949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } else { 1605949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int64_t durationUs; 1606949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1607949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen if (durationUs > 0) { 1608949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen int32_t frameRate = (nSamples * 1000000LL + 1609949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen (durationUs >> 1)) / durationUs; 1610949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1611949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen } 1612113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1613113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1614113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1615113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 161720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1621274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1622274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1623274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16240517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16250517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 162720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 162820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 162920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 163120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 163220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 163320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 163420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 163520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 163620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16374931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 16384931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 1639274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1640274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1641274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16430517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 16444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 16454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 16464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 16474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 16484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 16494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 16504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 16514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 16524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 16534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 16544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 165520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 1657274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) 1658274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake return ERROR_MALFORMED; 1659274f64c7d6367f13c7852256b10339a3b75529f2Joshua J. Drake 16600517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16610517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 166220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 166320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 166520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 166720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 167120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1673afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // \xA9xyz 1674e1b2ccf317301af42bb4b6631a3bcd7d8f519d00Chih-Hung Hsieh case FOURCC(0xA9, 'x', 'y', 'z'): 16754948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 16760517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 16770517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1678afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // Best case the total data length inside "\xA9xyz" box 1679afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/", 16804948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 16814948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 16824948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 16834948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 16844948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16854948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16864948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16874948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 16884948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 16894948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 16904948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 16914948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16924948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 16934948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 16944948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 16954948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 16964948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 16974948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 16984948818cb91176df74c972ac27b2f392b5d148bcJames Dong 16994948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 17004948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 17014948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 17024948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17034948818cb91176df74c972ac27b2f392b5d148bcJames Dong 17044948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 17054948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 17064948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 17074948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 17084948818cb91176df74c972ac27b2f392b5d148bcJames Dong 170920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 171020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 17110517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17120517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 171320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 171420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 171520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 171620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 171720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1718c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 171920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 172020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 172920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1732f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1733f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1734f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 173520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 173620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 173720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1738ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1739ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1740ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1741ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1742ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1743ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1744ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1745ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1746ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1747ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1748ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1749ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1750ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1751ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1752ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (mPath.size() >= 2 1753ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'v')) { 1754ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar // Check if the video is MPEG2 1755ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar ESDS esds(&buffer[4], chunk_data_size - 4); 1756ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar 1757ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar uint8_t objectTypeIndication; 1758ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) { 1759ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) { 1760ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); 1761ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1762ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 1763ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar } 176420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 176520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 176620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 176746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar case FOURCC('b', 't', 'r', 't'): 176846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar { 176946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar *offset += chunk_size; 177046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 177146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint8_t buffer[12]; 177246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (chunk_data_size != sizeof(buffer)) { 177346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return ERROR_MALFORMED; 177446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 177546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 177646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (mDataSource->readAt( 177746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar data_offset, buffer, chunk_data_size) < chunk_data_size) { 177846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return ERROR_IO; 177946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 178046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 178146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint32_t maxBitrate = U32_AT(&buffer[4]); 178246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar uint32_t avgBitrate = U32_AT(&buffer[8]); 178346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (maxBitrate > 0 && maxBitrate < INT32_MAX) { 178446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); 178546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 178646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (avgBitrate > 0 && avgBitrate < INT32_MAX) { 178746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate); 178846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 178946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar break; 179046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 179146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 179220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 179320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 17940517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 17950517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1796d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson sp<ABuffer> buffer = new ABuffer(chunk_data_size); 179720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17986a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 17996a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 18006a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 18016a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 18026a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen 180334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 1804d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1808f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1809f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1810f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 1812d2f6b04578432fa4e27bacf860b78bf29a099b73Jan Olof Svensson kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 181520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar case FOURCC('h', 'v', 'c', 'C'): 18173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar { 18183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(chunk_data_size); 18193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 18206a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 18216a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 18226a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 18236a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 18246a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen 18253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (mDataSource->readAt( 18263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 18273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_IO; 18283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 18293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 1830f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1831f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1832f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 18333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mLastTrack->meta->setData( 18343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); 18353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 18363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar *offset += chunk_size; 18373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar break; 18383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 183920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1840244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1841244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 18420517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 184317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 184417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 184517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 184617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 184717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 184817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 184917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 185017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 185117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 185217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 185317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 185417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 185517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 185617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1857ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size); 1858244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1859244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1860244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1861244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1862244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1863244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1864244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1865244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1866f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 1867f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 1868f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 1869244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1870244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1871244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1872244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1873244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 187472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 187572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 18768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stop_offset = *offset + chunk_size; 18778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset = data_offset; 18788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang bool isParsingMetaKeys = underQTMetaPath(mPath, 2); 18798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!isParsingMetaKeys) { 18808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint8_t buffer[4]; 18818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (chunk_data_size < (off64_t)sizeof(buffer)) { 18828ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 18838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 18848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 1885bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 18868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 18878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang data_offset, buffer, 4) < 4) { 18888ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 18898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_IO; 18908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 189172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 18928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (U32_AT(buffer) != 0) { 18938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // Should be version 0, flags 0. 1894ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 18958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // If it's not, let's assume this is one of those 18968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // apparently malformed chunks that don't have flags 18978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // and completely different semantics than what's 18988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // in the MPEG4 specs and skip it. 18998ee368522ca7df126033a05dc3c430182b4495c9Marco Nelissen *offset = stop_offset; 19008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 19018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 19028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += sizeof(buffer); 190372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 190472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 190572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 190672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 190772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 190872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 190972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 191072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1911bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1912bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 191572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 191672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 191772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 19185d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 19195d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 192072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 192172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 19220517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19230517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 192472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1925fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parseITunesMetaData(data_offset, chunk_data_size); 192672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 192772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 192872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 192972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 193072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 193172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 193272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 193372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 193472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 193572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 193672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 19370517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 19380517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 1939c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 32) { 194072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 194172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 194272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1943c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t header[32]; 194472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 194572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 194672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 194772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 194872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 194972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1950fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen uint64_t creationTime; 1951c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 195272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 195372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1954fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[20]); 1955c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = U64_AT(&header[24]); 1956c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 1957c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 1958c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1959bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1960bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 196172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 196272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 1963fc80e9ec5582770cb5a7fef172af3b52625ecce7Marco Nelissen mHeaderTimescale = U32_AT(&header[12]); 1964c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32 = U32_AT(&header[16]); 1965c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 1966c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 1967c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1968c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 1969c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 19703724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) { 1971c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 197272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 197372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 197472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 19753724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen if (convertTimeToDate(creationTime, &s)) { 19763724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen mFileMetaData->setCString(kKeyDate, s.string()); 19773724c1c9ab40ce2cc313686cd2532c79c025ca6aMarco Nelissen } 197872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 197972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 198072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 198172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 198272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1983c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('m', 'e', 'h', 'd'): 1984c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 1985c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 1986c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1987c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 8) { 1988c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 1989c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1990c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1991c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint8_t flags[4]; 1992c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (mDataSource->readAt( 1993c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen data_offset, flags, sizeof(flags)) 1994c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen < (ssize_t)sizeof(flags)) { 1995c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 1996c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 1997c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 1998c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t duration = 0; 1999c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (flags[0] == 1) { 2000c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 64 bit 2001c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 12) { 2002c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2003c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2004c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt64(data_offset + 4, &duration); 2005c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (duration == 0xffffffffffffffff) { 2006c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = 0; 2007c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2008c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (flags[0] == 0) { 2009c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen // 32 bit 2010c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint32_t d32; 2011c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDataSource->getUInt32(data_offset + 4, &d32); 2012c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (d32 == 0xffffffff) { 2013c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen d32 = 0; 2014c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2015c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen duration = d32; 2016c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else { 2017c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_MALFORMED; 2018c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2019c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2020e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (duration != 0 && mHeaderTimescale != 0) { 2021c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); 2022c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2024c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2025c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2026c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2027dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 2028dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 2029ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("mdat chunk, drm: %d", mIsDrm); 2030928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 2031928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang mMdatFound = true; 2032928da1e9631bc7f5a5484c4668646c161515aee6Chong Zhang 2033dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 2034dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 2035dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 2036dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2037dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2038dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 2039dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 2040dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2041dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2042dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 2043dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2044dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 20453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 20463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 20470517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 20480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2049ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang if (underQTMetaPath(mPath, 3)) { 2050ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang break; 2051ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang } 2052ef185e94ce624146e3b1f3cbdb2404e833a0f81dChong Zhang 20533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 20543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 20553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 20563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 20573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 20603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 2061e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 2062e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 2063e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 2064cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar if (mLastTrack != NULL) { 2065cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 2066cf75af8f76265fb2909028f5dc68c7029dbe5f49Lajos Molnar } 20673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 20703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 20713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 20728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang case FOURCC('k', 'e', 'y', 's'): 20738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang { 20748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang *offset += chunk_size; 20758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 20768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 20778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaKey(data_offset, chunk_data_size); 20788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 20798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang break; 20808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 20818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 2082c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen case FOURCC('t', 'r', 'e', 'x'): 2083c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen { 2084c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen *offset += chunk_size; 2085c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2086c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (chunk_data_size < 24) { 2087c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2088c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2089c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex trex; 2090c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) || 2091c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) || 2092c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) || 2093c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) || 2094c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) { 2095c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen return ERROR_IO; 2096c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2097c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex.add(trex); 2098c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 2099c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 2100c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 21017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 21027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 2103f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2104f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2105f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 21063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 21073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 21083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 21093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 21103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 21113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 21123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21140e20b2093aa2bbc93afed8d68d3765d18a431b74Nick Kralevich if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) { 2115dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake return ERROR_MALFORMED; 2116dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake } 2117dc69f4856187904bfb0d12a72cdf5a563a0deff2Joshua J. Drake 21188da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size]; 21198da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 21208da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 21218da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 21223b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21233b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 21243b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 21253b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21263b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21273b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 21283b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 21293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 21303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 21313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21320517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen // advance read pointer so we don't end up reading this again 21330517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 21353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 21363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 21383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 21393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 21403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 21417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 21427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 21437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 21447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 21457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 2146515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 2147515e855eae78aa495da58356486aaa666cb57fd1James Dong { 21480517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 21490517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2150515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 2151635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, 2152635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert chunk_data_size, data_offset); 21531e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake 2154635bc8f90429b2fdcaf7f8d43f7f59bcd0fe951cDan Albert if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) { 21551e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake return ERROR_MALFORMED; 21561e51401794ff830c912c21123c321b83c17b491dJoshua J. Drake } 21571552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 21586a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen if (buffer->data() == NULL) { 21596a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen ALOGE("b/28471206"); 21606a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen return NO_MEMORY; 21616a456937c0d42fd8617126afdbf9e41087cf3cbcMarco Nelissen } 2162515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 21631552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 2164515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 2165515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2166515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 216797d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake if (chunk_data_size <= kSkipBytesOfDataBox) { 216897d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake return ERROR_MALFORMED; 216997d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake } 217097d45dbfdfc9018f1cbf72641c1447ff59431ae3Joshua J. Drake 2171515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 2172515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 21731552217cca4d949bba4b2cf6194a0936bbb10fa4Jens Gulin buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 2174515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2175515e855eae78aa495da58356486aaa666cb57fd1James Dong 2176515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 2177515e855eae78aa495da58356486aaa666cb57fd1James Dong } 2178515e855eae78aa495da58356486aaa666cb57fd1James Dong 217958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar case FOURCC('c', 'o', 'l', 'r'): 218058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar { 218158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar *offset += chunk_size; 218258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd') 218358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // ignore otherwise 218458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) { 218558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar status_t err = parseColorInfo(data_offset, chunk_data_size); 218658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (err != OK) { 218758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return err; 218858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 218958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 219058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 219158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar break; 219258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 219358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2194fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2195fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2196fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2197fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2198fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2199fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2200fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 22010517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 22020517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2203fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 2204fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2205fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (err != OK) { 2206fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return err; 2207fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2208fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2209fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2210fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2211fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2212328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé case FOURCC('I', 'D', '3', '2'): 2213328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { 22140517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen *offset += chunk_size; 22150517e0b6e4a86f34388631416dd6b3b4fcb91ff8Marco Nelissen 2216328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (chunk_data_size < 6) { 2217328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé return ERROR_MALFORMED; 2218328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2219328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2220328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé parseID3v2MetaData(data_offset + 6); 2221328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2222328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé break; 2223328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2224328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 22255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 22265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 22275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 22285d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 22295d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 22305d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 22315d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 22325d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 22335d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 223405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('s', 'i', 'd', 'x'): 223505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen { 223605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseSegmentIndex(data_offset, chunk_data_size); 223705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 223805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return UNKNOWN_ERROR; // stop parsing after sidx 223905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 224005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 224120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 224220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 22438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // check if we're parsing 'ilst' for meta keys 22448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // if so, treat type as a number (key-id). 22458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (underQTMetaPath(mPath, 3)) { 22468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang parseQTMetaVal(chunk_type, data_offset, chunk_data_size); 22478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 22488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 224920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 225020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 225120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 225220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 225320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 225420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 225520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 225620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 225705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 225805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseSegmentIndex"); 225905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 226005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 12) { 226105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 226205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 226305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 226405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 226505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 226605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 226705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 226805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 226905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t version = flags >> 24; 227005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen flags &= 0xffffff; 227105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 227205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx version %d", version); 227305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 227405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t referenceId; 227505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 227605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 227705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 227805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 227905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t timeScale; 228005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 228105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 228205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 228305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 2284e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake if (timeScale == 0) 2285e3e82d54c51a3130badcd9e433fe808d965f15c2Joshua J. Drake return ERROR_MALFORMED; 228605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 228705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t earliestPresentationTime; 228805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t firstOffset; 228905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 229005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 229105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 12; 229205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 229305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (version == 0) { 229405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 229505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 229605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 229705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t tmp; 229805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 229905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 230005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 230105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen earliestPresentationTime = tmp; 230205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &tmp)) { 230305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 230405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 230505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen firstOffset = tmp; 230605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 230705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 230805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 230905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 16) { 231005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 231105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 231205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 231305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 231405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 231505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 231605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 231705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 231805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 16; 231905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 16; 232005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 2321a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset); 232205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 232305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 232405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 232505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 232605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 232705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint16_t referenceCount; 232805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 232905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 233005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 233105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 233205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 233305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("refcount: %d", referenceCount); 233405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 233505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < referenceCount * 12) { 233605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 233705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 233805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 233905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t total_duration = 0; 234005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (unsigned int i = 0; i < referenceCount; i++) { 234105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t d1, d2, d3; 234205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 234305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &d1) || // size 234405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 4, &d2) || // duration 234505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen !mDataSource->getUInt32(offset + 8, &d3)) { // flags 234605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 234705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 234805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 234905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (d1 & 0x80000000) { 235005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGW("sub-sidx boxes not supported yet"); 235105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 235205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool sap = d3 & 0x80000000; 23533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen uint32_t saptype = (d3 >> 28) & 7; 23543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (!sap || (saptype != 1 && saptype != 2)) { 23553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // type 1 and 2 are sync samples 23563f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen ALOGW("not a stream access point, or unsupported type: %08x", d3); 235705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 235805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen total_duration += d2; 235905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 12; 236005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 236105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen SidxEntry se; 236205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mSize = d1 & 0x7fffffff; 236305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 236405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSidxEntries.add(se); 236505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 236605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2367c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen uint64_t sidxDuration = total_duration * 1000000 / timeScale; 236805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2369f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2370f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2371f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 237205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t metaDuration; 237305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 2374c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); 237505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 237605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 237705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 237805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 23798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) { 23808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size < 8) { 23818cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23828cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23838cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23848cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t count; 23858cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &count)) { 23868cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23878cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23888cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23898cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mMetaKeyMap.size() > 0) { 23908cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGW("'keys' atom seen again, discarding existing entries"); 23918cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.clear(); 23928cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 23938cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 23948cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t keyOffset = offset + 8; 23958cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang off64_t stopOffset = offset + size; 23968cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang for (size_t i = 1; i <= count; i++) { 23978cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyOffset + 8 > stopOffset) { 23988cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 23998cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24008cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24018cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t keySize; 24028cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset, &keySize) 24038cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keySize < 8 24048cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || keyOffset + keySize > stopOffset) { 24058cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24068cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24078cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24088cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t type; 24098cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(keyOffset + 4, &type) 24108cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || type != FOURCC('m', 'd', 't', 'a')) { 24118cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24128cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24138cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24148cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keySize -= 8; 24158cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += 8; 24168cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24178cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang sp<ABuffer> keyData = new ABuffer(keySize); 24188cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (keyData->data() == NULL) { 24198cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24208cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24218cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (mDataSource->readAt( 24228cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset, keyData->data(), keySize) < (ssize_t) keySize) { 24238cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24248cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24258cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24268cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang AString key((const char *)keyData->data(), keySize); 24278cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mMetaKeyMap.add(i, key); 24288cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24298cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang keyOffset += keySize; 24308cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24318cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 24328cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 24338cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24348cfad968d5ec429b033caff9743f1ef15090be61Chong Zhangstatus_t MPEG4Extractor::parseQTMetaVal( 24358cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang int32_t keyId, off64_t offset, size_t size) { 24368cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ssize_t index = mMetaKeyMap.indexOfKey(keyId); 24378cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (index < 0) { 24388cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // corresponding key is not present, ignore 24398cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24408cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 244105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 24428cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (size <= 16) { 24438cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24448cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24458cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataSize; 24468cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &dataSize) 24478cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || dataSize > size || dataSize <= 16) { 24488cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24498cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24508cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t atomFourCC; 24518cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 4, &atomFourCC) 24528cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || atomFourCC != FOURCC('d', 'a', 't', 'a')) { 24538cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24548cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24558cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t dataType; 24568cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset + 8, &dataType) 24578cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang || ((dataType & 0xff000000) != 0)) { 24588cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // not well-known type 24598cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24608cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24618cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24628cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang dataSize -= 16; 24638cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang offset += 16; 24648cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24658cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (dataType == 23 && dataSize >= 4) { 24668cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // BE Float32 24678cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang uint32_t val; 24688cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!mDataSource->getUInt32(offset, &val)) { 24698cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return ERROR_MALFORMED; 24708cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24718cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) { 24728cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val); 24738cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24748cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } else { 24758cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang // add more keys if needed 24768cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang ALOGV("ignoring key: type %d, size %d", dataType, dataSize); 24778cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang } 24788cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang 24798cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang return OK; 24808cfad968d5ec429b033caff9743f1ef15090be61Chong Zhang} 248105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 2482ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 2483c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 2484ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 2485ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2486ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2487ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2488ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 2489ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 2490ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2491ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2492ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2493ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 2494ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2495ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 2496ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2497c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 2498ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 2499ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2500ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2501ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 2502ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 2503ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 2504ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2505ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2506b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint64_t ctime __unused, mtime __unused, duration __unused; 2507ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 2508ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2509ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 2510ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 2511ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 2512ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 2513ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 251404022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else if (version == 0) { 2515ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 2516ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 2517ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 2518ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 251904022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen } else { 252004022b34d2b97938b0926ab62e6c283418da3bbaMarco Nelissen return ERROR_UNSUPPORTED; 2521ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2522ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2523f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2524f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2525f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 2526ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 2527ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2528ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 2529ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 2530ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2531ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2532ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2533ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2534ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 2535b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2536b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2537b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe 2538df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2539ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2540df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2541ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2542ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 2543ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2544ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 2545ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2546ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 2547ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2548ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 2549ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2550ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2551ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 2552ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2553ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 2554ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2555ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 2556ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 25575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2558ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 2559ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2560ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2561ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 2562ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2563ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 2564ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2565b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 2566b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 2567ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 2568ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 2569b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2570b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2571ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2572ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 2573ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 2574ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 2575fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 2576c570778430a22b5488cae72982cf9fb8033dbda3Nick Kralevich if (size < 4 || size == SIZE_MAX) { 257772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 257872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 257972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 25808da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 25818da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 25828da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 25838da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 258472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 258572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 258672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 258772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 258872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 258972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 259072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 259172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 259272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 259372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 259472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 25955d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 25965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 2597ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("meta: %s @ %lld", chunk, (long long)offset); 25982d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer switch ((int32_t)mPath[4]) { 259972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 260072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 260172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 260272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 260372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 260472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 260572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 260672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 260772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 260872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 260966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 261066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 261166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 261266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 261366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 261472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 261572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 261672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 261772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 261872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 261972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 262072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 262172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 262272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 262372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 262472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 262572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 262672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 262772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 262872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 262972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 263072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 263172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 263272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 263372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 263472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 263572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 263672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 263772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 263872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 263926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 264026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 264126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 264226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 264326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 264411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 264511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 264611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 264711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 264811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 264911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 265011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 265111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 265211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 265311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 265411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 265572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 265672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 265772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 265872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 2659afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTrack = (uint16_t*)&buffer[10]; 2660afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2661afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 266272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 266372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 266472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 266572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 266672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 266726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 266826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 2669afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik if ((size == 14 || size == 16) && flags == 0) { 267026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 2671afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pDisc = (uint16_t*)&buffer[10]; 2672afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2673afa28a823724a2f76e1a53b15358533388003666Andreas Lillvik sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 267426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 267526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 267626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 267726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 267826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 26795d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 26805d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 26815d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 26825d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 26835d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 26845d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 26855d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 26865d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 26875d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 26885d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 26895d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 26905cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia if (size < 8) { 26915cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia delete[] buffer; 26925cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia buffer = NULL; 26935cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia ALOGE("b/24346430"); 26945cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia return ERROR_MALFORMED; 26955cae16bdce77b0a3ba590b55637f7d55a2f35402Wei Jia } 26965d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 26975d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 26985d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 26998c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 27008c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // Once we have a set of mean/name/data info, go ahead and process 27018c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // it to see if its something we are interested in. Whether or not 27028c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // were are interested in the specific tag, make sure to clear out 27038c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // the set so we can be ready to process another tuple should one 27048c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman // show up later in the file. 27058c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if ((mLastCommentMean.length() != 0) && 27068c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentName.length() != 0) && 27078c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman (mLastCommentData.length() != 0)) { 27088c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 27098c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (mLastCommentMean == "com.apple.iTunes" 27108c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman && mLastCommentName == "iTunSMPB") { 27118c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman int32_t delay, padding; 27128c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman if (sscanf(mLastCommentData, 27138c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman " %*x %x %x %*x", &delay, &padding) == 2) { 2714f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 2715f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 2716f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 27178c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 27188c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 27198c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman } 27205d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 27218c7d147cca17961a71209c105a2676a552d3d69fJohn Grossman 27225d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 27235d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 27245d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 27255d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 27265d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 27275d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 272826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 272972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 273072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 273172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 273272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 2733328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 273472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 273572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 273672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 273772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 273872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 273972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 274026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 274126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 274226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 274326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 274426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 274526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 274626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 274726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 274826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 274972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 275026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 275172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 275272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 275326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 275426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 275526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 275626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 275726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 275826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 275972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 276072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 276172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 276272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 276372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 276472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 276572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 276672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 276772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 276872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 276972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 277072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 277172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 277272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 277372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 277458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarstatus_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { 277558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) { 277658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 277758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 277858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 277958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 278058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (buffer == NULL) { 278158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_MALFORMED; 278258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 278358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) { 278458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 278558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 278658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 278758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return ERROR_IO; 278858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 278958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 279058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t type = U32_AT(&buffer[0]); 279158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11) 279258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) { 279358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t primaries = U16_AT(&buffer[4]); 279458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t transfer = U16_AT(&buffer[6]); 279558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar int32_t coeffs = U16_AT(&buffer[8]); 279658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128); 279758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 279858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorAspects aspects; 279958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar ColorUtils::convertIsoColorAspectsToCodecAspects( 280058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar primaries, transfer, coeffs, fullRange, aspects); 280158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 280258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar // only store the first color specification 280358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { 280458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); 280558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); 280658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); 280758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); 280858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 280958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 281058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 281158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar delete[] buffer; 281258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar buffer = NULL; 281358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 281458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar return OK; 281558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar} 281658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar 2817fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhéstatus_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 28185cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake if (size < 4 || size == SIZE_MAX) { 2819fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_MALFORMED; 2820fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2821fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 28225cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; 28238da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (buffer == NULL) { 28248da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 28258da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 2826fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (mDataSource->readAt( 2827fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé offset, buffer, size) != (ssize_t)size) { 2828fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2829fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2830fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2831fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return ERROR_IO; 2832fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2833fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2834fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint32_t metadataKey = 0; 2835fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé switch (mPath[depth]) { 2836fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('t', 'i', 't', 'l'): 2837fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2838fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyTitle; 2839fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2840fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2841fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('p', 'e', 'r', 'f'): 2842fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2843fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyArtist; 2844fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2845fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2846fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'u', 't', 'h'): 2847fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2848fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyWriter; 2849fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2850fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2851fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('g', 'n', 'r', 'e'): 2852fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2853fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyGenre; 2854fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2855fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2856fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('a', 'l', 'b', 'm'): 2857fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2858fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (buffer[size - 1] != '\0') { 2859fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[4]; 2860fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", buffer[size - 1]); 2861fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2862fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2863fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2864fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2865fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé metadataKey = kKeyAlbum; 2866fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2867fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2868fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé case FOURCC('y', 'r', 'r', 'c'): 2869fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé { 2870fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char tmp[5]; 2871fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé uint16_t year = U16_AT(&buffer[4]); 2872fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2873fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (year < 10000) { 2874fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé sprintf(tmp, "%u", year); 2875fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2876fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(kKeyYear, tmp); 2877fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2878fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2879fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2880fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2881fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé default: 2882fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé break; 2883fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2884fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2885fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (metadataKey > 0) { 2886fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé bool isUTF8 = true; // Common case 2887fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé char16_t *framedata = NULL; 2888fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé int len16 = 0; // Number of UTF-16 characters 2889fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2890fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 28919458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake if (size < 6) { 28929458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake return ERROR_MALFORMED; 28939458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake } 28949458e715d391ee8fe455fc31f07ff35ce12e0531Joshua J. Drake 2895fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (size - 6 >= 4) { 2896fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2897fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata = (char16_t *)(buffer + 6); 2898fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfffe == *framedata) { 2899fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // endianness marker (BOM) doesn't match host endianness 2900fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé for (int i = 0; i < len16; i++) { 2901fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata[i] = bswap_16(framedata[i]); 2902fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2903fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // BOM is now swapped to 0xfeff, we will execute next block too 2904fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2905fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2906fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (0xfeff == *framedata) { 2907fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Remove the BOM 2908fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé framedata++; 2909fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé len16--; 2910fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé isUTF8 = false; 2911fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2912fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // else normal non-zero-length UTF-8 string 2913fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // we can't handle UTF-16 without BOM as there is no other 2914fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // indication of encoding. 2915fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2916fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2917fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé if (isUTF8) { 29185cea0155cfc41f67e91343c342f44251c03fde3aJoshua J. Drake buffer[size] = 0; 2919fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2920fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } else { 2921fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé // Convert from UTF-16 string to UTF-8 string. 2922fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé String8 tmpUTF8str(framedata, len16); 2923fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2924fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2925fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé } 2926fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2927fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé delete[] buffer; 2928fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé buffer = NULL; 2929fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2930fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé return OK; 2931fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé} 2932fbc9d2b9cda433d98c36acb842c4a91fdeeb75e0Oscar Rydhé 2933328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhévoid MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2934328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3 id3(mDataSource, true /* ignorev1 */, offset); 2935328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2936328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (id3.isValid()) { 2937328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé struct Map { 2938328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé int key; 2939328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag1; 2940328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const char *tag2; 2941328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2942328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const Map kMap[] = { 2943328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbum, "TALB", "TAL" }, 2944328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyArtist, "TPE1", "TP1" }, 2945328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAlbumArtist, "TPE2", "TP2" }, 2946328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyComposer, "TCOM", "TCM" }, 2947328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyGenre, "TCON", "TCO" }, 2948328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyTitle, "TIT2", "TT2" }, 2949328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyYear, "TYE", "TYER" }, 2950328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyAuthor, "TXT", "TEXT" }, 2951328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCDTrackNumber, "TRK", "TRCK" }, 2952328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyDiscNumber, "TPA", "TPOS" }, 2953328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé { kKeyCompilation, "TCP", "TCMP" }, 2954328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé }; 2955328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2956328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2957328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé for (size_t i = 0; i < kNumMapEntries; ++i) { 2958328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (!mFileMetaData->hasData(kMap[i].key)) { 2959328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2960328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2961328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2962328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it = new ID3::Iterator(id3, kMap[i].tag2); 2963328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2964328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2965328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (it->done()) { 2966328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2967328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé continue; 2968328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2969328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2970328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 s; 2971328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé it->getString(&s); 2972328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé delete it; 2973328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2974328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kMap[i].key, s); 2975328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2976328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2977328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2978328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé size_t dataSize; 2979328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé String8 mime; 2980328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé const void *data = id3.getAlbumArt(&dataSize, &mime); 2981328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2982328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (data) { 2983328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2984328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2985328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2986328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé } 2987328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé} 2988328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé 2989b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG4Extractor::getTrack(size_t index) { 299020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 299120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 2992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 299320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 299420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 299520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 299620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 299720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 2998693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 299920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 300020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 300120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 300220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 300320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 300420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3005371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 3006371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 3007371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 3008371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3009c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3010c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen Trex *trex = NULL; 3011c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int32_t trackId; 3012c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (track->meta->findInt32(kKeyTrackID, &trackId)) { 3013c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen for (size_t i = 0; i < mTrex.size(); i++) { 3014949d857ea24950ff920820b4ccf78133dcc737d1Marco Nelissen Trex *t = &mTrex.editItemAt(i); 3015c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen if (t->track_ID == (uint32_t) trackId) { 3016c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen trex = t; 3017c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen break; 3018c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 3019c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 30200386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } else { 30210386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia ALOGE("b/21657957"); 30220386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia return NULL; 3023c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 3024c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3025a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("getTrack called, pssh: %zu", mPssh.size()); 3026ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3027a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const char *mime; 3028a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findCString(kKeyMIMEType, &mime)) { 3029a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3030a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3031a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3032a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 3033a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 3034a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 3035a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 3036a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) { 3037a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3038a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3039a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3040a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 3041a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3042a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 3043a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3044a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3045a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 3046a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia uint32_t type; 3047a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const void *data; 3048a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia size_t size; 3049a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) { 3050a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3051a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3052a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3053a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia const uint8_t *ptr = (const uint8_t *)data; 3054a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3055a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia if (size < 22 || ptr[0] != 1) { // configurationVersion == 1 3056a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia return NULL; 3057a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3058a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia } 3059a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia 3060942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen return new MPEG4Source(this, 306105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen track->meta, mDataSource, track->timescale, track->sampleTable, 3062c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mSidxEntries, trex, mMoofOffset); 306320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 306420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3065bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 3066bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 3067bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 3068bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3069bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3070bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 3071bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 3072bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 3073bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 3074bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 3075bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 3076bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 3077bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 30783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 30793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!track->meta->findData(kKeyHVCC, &type, &data, &size) 30803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar || type != kTypeHVCC) { 30813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar return ERROR_MALFORMED; 30823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3083bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 3084ae0c0a17e824356eb55a6692ff8dee6cdc050401Harish Mahendrakar || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) 3085bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 3086bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 3087bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 3088bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 3089bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 3090bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 3091bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3092ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih if (track->sampleTable == NULL || !track->sampleTable->isValid()) { 3093169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 3094ce171998009e1abcb0c718c0aee495fcd33645e2Robert Shih ALOGE("stbl atom missing/invalid."); 3095169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 3096169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 3097169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 30982e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang if (track->timescale == 0) { 30992e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang ALOGE("timescale invalid."); 31002e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang return ERROR_MALFORMED; 31012e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang } 31022e81b588f2cc54eaa4f9c83cce279589fb221523Dan Liang 3103bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 3104bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 3105bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 3106f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivitypedef enum { 3107f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NONE = -1, 3108f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_NULL_OBJECT = 0, 3109f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_MAIN = 1, /**< Main profile */ 3110f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_AAC_LC = 2, /**< Low Complexity object */ 3111f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SSR = 3, 3112f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_LTP = 4, 3113f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_SBR = 5, 3114f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SCAL = 6, 3115f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TWIN_VQ = 7, 3116f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_CELP = 8, 3117f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_HVXC = 9, 3118f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_10 = 10, /**< (reserved) */ 3119f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_11 = 11, /**< (reserved) */ 3120f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_TTSI = 12, /**< TTSI Object */ 3121f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 3122f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 3123f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_GEN_MIDI = 15, /**< General MIDI object */ 3124f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 3125f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 3126f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_18 = 18, /**< (reserved) */ 3127f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 3128f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 3129f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 3130f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 3131f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 3132f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 3133f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 3134f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 3135f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 3136f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_28 = 28, /**< might become SSC */ 3137f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 3138f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MPEGS = 30, /**< MPEG Surround */ 3139f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3140f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 3141f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3142f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 3143f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 3144f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 3145f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_35 = 35, /**< might become DST */ 3146f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD_36 = 36, /**< might become ALS */ 3147f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_AAC_SLS = 37, /**< AAC + SLS */ 3148f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SLS = 38, /**< SLS */ 3149f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 3150f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3151f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_USAC = 42, /**< USAC */ 3152f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_SAOC = 43, /**< SAOC */ 3153f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 3154f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3155f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 3156f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi} AUDIO_OBJECT_TYPE; 3157f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3158ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 3159ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 3160ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 316181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 316281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 316381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 316481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 316581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 316681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 316781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 316881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 3169f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3170f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3171f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 317281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 317381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 317481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 317581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 3176633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 3177633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 3178633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 3179633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 318029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 3181633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 3182633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 3183633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 3184ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 3185ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 3186ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 3187ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 3188ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3189ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3190ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3191b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe if (kUseHexDump) { 3192ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar printf("ESD of size %zu\n", csd_size); 3193b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe hexdump(csd, csd_size); 3194b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe } 3195ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3196a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 3197a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 3198a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 3199a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 3200a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3201a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 3202a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 3203a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 3204ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 3205ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 3206ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3207ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 320800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent static uint32_t kSamplingRate[] = { 320900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 321000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 16000, 12000, 11025, 8000, 7350 321100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent }; 321200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 3213aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke ABitReader br(csd, csd_size); 3214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t objectType = br.getBits(5); 3215ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3216aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (objectType == 31) { // AAC-ELD => additional 6 bits 3217aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke objectType = 32 + br.getBits(6); 3218ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3219ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3220f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3221f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3222f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3223db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent //keep AOT type 3224db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 3225db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 3226aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke uint32_t freqIndex = br.getBits(4); 3227aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 3228ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 3229ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 3230ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 32318e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 28) return ERROR_MALFORMED; 3232aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke sampleRate = br.getBits(24); 3233aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke numChannels = br.getBits(4); 3234ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 32358e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3236595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen numChannels = br.getBits(4); 323700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent 323800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (freqIndex == 13 || freqIndex == 14) { 323900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 3240ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3241ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 324200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent sampleRate = kSamplingRate[freqIndex]; 324300307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 3244595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen 3245f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 32468e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 324700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent uint32_t extFreqIndex = br.getBits(4); 3248b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe int32_t extSampleRate __unused; 324900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 15) { 325000307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (csd_size < 8) { 3251595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen return ERROR_MALFORMED; 3252595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 32538e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 24) return ERROR_MALFORMED; 325400307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = br.getBits(24); 325500307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } else { 325600307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent if (extFreqIndex == 13 || extFreqIndex == 14) { 325700307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent return ERROR_MALFORMED; 325800307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent } 325900307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent extSampleRate = kSamplingRate[extFreqIndex]; 3260595ee7ba5f988ff34527226d0142a109ca3b049eMarco Nelissen } 326100307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent //TODO: save the extension sampling rate value in meta data => 326200307ade843ac9219ffb9a351a3145ec2927ea51Eric Laurent // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 3263ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3264ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3265f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi switch (numChannels) { 3266f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 3267f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 0: 3268f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 1:// FC 3269f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 2:// FL FR 3270f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 3:// FC, FL FR 3271f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 4:// FC, FL FR, RC 3272f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 5:// FC, FL FR, SL SR 3273f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 6:// FC, FL FR, SL SR, LFE 3274f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi //numChannels already contains the right value 3275f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3276f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 11:// FC, FL FR, SL SR, RC, LFE 3277f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 7; 3278f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3279f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 7: // FC, FCL FCR, FL FR, SL SR, LFE 3280f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 12:// FC, FL FR, SL SR, RL RR, LFE 3281f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi case 14:// FC, FL FR, SL SR, LFE, FHL FHR 3282f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = 8; 3283f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi break; 3284f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi default: 3285f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi return ERROR_UNSUPPORTED; 3286f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3287f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3288f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi { 3289f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_SBR || objectType == AOT_PS) { 32908e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3291f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = br.getBits(5); 3292f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3293f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_ESCAPE) { 32948e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 6) return ERROR_MALFORMED; 3295f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType = 32 + br.getBits(6); 3296f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3297f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3298f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 3299f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 3300f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi objectType == AOT_ER_BSAC) { 33018e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 2) return ERROR_MALFORMED; 3302b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t frameLengthFlag __unused = br.getBits(1); 3303f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3304f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t dependsOnCoreCoder = br.getBits(1); 3305f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3306f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (dependsOnCoreCoder ) { 33078e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 14) return ERROR_MALFORMED; 3308b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t coreCoderDelay __unused = br.getBits(14); 3309f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3310f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 331145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih int32_t extensionFlag = -1; 331245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (br.numBitsLeft() > 0) { 331345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = br.getBits(1); 331445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } else { 331545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih switch (objectType) { 331645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih // 14496-3 4.5.1.1 extensionFlag 331745452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_AAC_LC: 331845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 0; 331945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 332045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LC: 332145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_SCAL: 332245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_BSAC: 332345452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih case AOT_ER_AAC_LD: 332445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag = 1; 332545452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 332645452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih default: 33278e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 332845452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih break; 332945452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 333045452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih ALOGW("csd missing extension flag; assuming %d for object type %u.", 333145452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih extensionFlag, objectType); 333245452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih } 3333f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 333445452ffeb3827dd3c955aca1b4ab3522b70cf8ccRobert Shih if (numChannels == 0) { 3335f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsEffectiveNum = 0; 3336f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int32_t channelsNum = 0; 33378e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 32) { 33388e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen return ERROR_MALFORMED; 33398e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen } 3340b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t ElementInstanceTag __unused = br.getBits(4); 3341b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t Profile __unused = br.getBits(2); 3342b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SamplingFrequencyIndex __unused = br.getBits(4); 3343f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumFrontChannelElements = br.getBits(4); 3344f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumSideChannelElements = br.getBits(4); 3345f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumBackChannelElements = br.getBits(4); 3346f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t NumLfeChannelElements = br.getBits(2); 3347b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumAssocDataElements __unused = br.getBits(3); 3348b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t NumValidCcElements __unused = br.getBits(4); 3349f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3350f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MonoMixdownPresent = br.getBits(1); 33518e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen 3352f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MonoMixdownPresent != 0) { 33538e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3354b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MonoMixdownElementNumber __unused = br.getBits(4); 3355f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3356f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 33578e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3358f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t StereoMixdownPresent = br.getBits(1); 3359f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (StereoMixdownPresent != 0) { 33608e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3361b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t StereoMixdownElementNumber __unused = br.getBits(4); 3362f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3363f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 33648e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 1) return ERROR_MALFORMED; 3365f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t MatrixMixdownIndexPresent = br.getBits(1); 3366f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi if (MatrixMixdownIndexPresent != 0) { 33678e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 3) return ERROR_MALFORMED; 3368b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t MatrixMixdownIndex __unused = br.getBits(2); 3369b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t PseudoSurroundEnable __unused = br.getBits(1); 3370f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3371f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3372f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi int i; 3373f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumFrontChannelElements; i++) { 33748e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3375f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t FrontElementIsCpe = br.getBits(1); 3376b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t FrontElementTagSelect __unused = br.getBits(4); 3377f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += FrontElementIsCpe ? 2 : 1; 3378f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3379f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3380f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumSideChannelElements; i++) { 33818e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3382f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t SideElementIsCpe = br.getBits(1); 3383b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t SideElementTagSelect __unused = br.getBits(4); 3384f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += SideElementIsCpe ? 2 : 1; 3385f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3386f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3387f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumBackChannelElements; i++) { 33888e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 5) return ERROR_MALFORMED; 3389f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi const int32_t BackElementIsCpe = br.getBits(1); 3390b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t BackElementTagSelect __unused = br.getBits(4); 3391f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += BackElementIsCpe ? 2 : 1; 3392f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3393f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsEffectiveNum = channelsNum; 3394f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3395f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi for (i=0; i < NumLfeChannelElements; i++) { 33968e0cc331a5b2e24016d8c5b8da11591cdd7c0fc0Marco Nelissen if (br.numBitsLeft() < 4) return ERROR_MALFORMED; 3397b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe const int32_t LfeElementTagSelect __unused = br.getBits(4); 3398f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi channelsNum += 1; 3399f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3400f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 3401f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 3402f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi numChannels = channelsNum; 3403f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3404f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3405f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi } 3406f4512c9672110c11b7bdeea0073a54bfae9c8f87Jean-Michel Trivi 3407ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 3408ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 3409ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3410ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3411f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake if (mLastTrack == NULL) 3412f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake return ERROR_MALFORMED; 3413f35ff157134456d30f4cd32b463e32bbbf796cc9Joshua J. Drake 3414ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 3415ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 3416ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3417ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 34183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 3419ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 3420ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3421ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3422ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 3423ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3424ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 3425ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 3426ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3427ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 34283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 3429ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 3430ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 3431ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3432ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 3433ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 3434ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 3435ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 3436ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 343720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 343820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 343920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 3440942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen const sp<MPEG4Extractor> &owner, 344120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 3442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 344348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 344405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const sp<SampleTable> &sampleTable, 344505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Vector<SidxEntry> &sidx, 3446c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen const Trex *trex, 344705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t firstMoofOffset) 3448942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen : mOwner(owner), 3449942481eee58cb1e81853bc79e25359a7ee8a59e1Marco Nelissen mFormat(format), 345020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 345148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 345220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 345320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 345405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentFragmentIndex(0), 345505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mSegments(sidx), 3456c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mTrex(trex), 345705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mFirstMoofOffset(firstMoofOffset), 345805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset(firstMoofOffset), 345905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime(0), 3460ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize(0), 3461ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes(NULL), 3462ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize(0), 3463ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets(NULL), 346420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 34653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC(false), 34666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 346720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 346820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 346920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 3470dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 34710024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 3472ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3473c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); 3474c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 3475ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 347648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mDefaultIVSize = 0; 3477ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 3478ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t keytype; 3479ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *key; 3480ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t keysize; 3481ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 3482ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(keysize <= 16); 3483ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(mCryptoKey, 0, 16); 3484ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(mCryptoKey, key, keysize); 3485ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3486ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 348720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 348820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 3489dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 349020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 349118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 34923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); 34936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 34946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 34956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 34966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 34976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 34986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 34996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 35016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 3503ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 35046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 35056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 35066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 35073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (mIsHEVC) { 35083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint32_t type; 35093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const void *data; 35103b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t size; 35113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(format->findData(kKeyHVCC, &type, &data, &size)); 35123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 35133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 35143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3515a44ad9cefb0e2ff4091c8f58368c8b94779212aaWei Jia CHECK(size >= 22); 35163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 35173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 35183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar mNALLengthSize = 1 + (ptr[14 + 7] & 3); 35196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 352005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 352205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 352305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset != 0) { 352405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = mFirstMoofOffset; 352505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&offset); 352605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 352720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 352820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 352920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 353020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 353120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 353220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3533ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoSizes); 3534ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen free(mCurrentSampleInfoOffsets); 353520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 353620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 353720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 35387b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 35397b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3540dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 354120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 354220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 3543dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 354420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 3545dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 354620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 3547dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 354820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 354920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3550afd492436efc7f66b958da14659b52232efa5910Marco Nelissen int32_t tmp; 3551afd492436efc7f66b958da14659b52232efa5910Marco Nelissen CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp)); 3552afd492436efc7f66b958da14659b52232efa5910Marco Nelissen size_t max_size = tmp; 355320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3554afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // A somewhat arbitrary limit that should be sufficient for 8k video frames 3555afd492436efc7f66b958da14659b52232efa5910Marco Nelissen // If you see the message below for a valid input stream: increase the limit 3556afd492436efc7f66b958da14659b52232efa5910Marco Nelissen if (max_size > 64 * 1024 * 1024) { 3557afd492436efc7f66b958da14659b52232efa5910Marco Nelissen ALOGE("bogus max input size: %zu", max_size); 3558afd492436efc7f66b958da14659b52232efa5910Marco Nelissen return ERROR_MALFORMED; 3559afd492436efc7f66b958da14659b52232efa5910Marco Nelissen } 3560afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = new MediaBufferGroup; 3561738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 35620024245e134467d120b40099da16c467dc365e76Andreas Huber 35638da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen mSrcBuffer = new (std::nothrow) uint8_t[max_size]; 35648da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen if (mSrcBuffer == NULL) { 35658da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen // file probably specified a bad max size 3566afd492436efc7f66b958da14659b52232efa5910Marco Nelissen delete mGroup; 3567afd492436efc7f66b958da14659b52232efa5910Marco Nelissen mGroup = NULL; 35688da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen return ERROR_MALFORMED; 35698da8b2e80ccdb10ff2445f503829f803d3a6ab9fMarco Nelissen } 357020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 357120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 357220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 357320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 357420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 357520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 357620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 35777b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 35787b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 3579dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 358020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 358120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 358220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 358320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 358420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 358520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35860024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 35870024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 35880024245e134467d120b40099da16c467dc365e76Andreas Huber 358920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 359020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 359120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 359220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 359320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 359420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 359520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 359620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 359720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 359805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseChunk(off64_t *offset) { 359905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t hdr[2]; 360005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 360105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 360205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 360305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t chunk_size = ntohl(hdr[0]); 360405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t chunk_type = ntohl(hdr[1]); 360505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t data_offset = *offset + 8; 360605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 360705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size == 1) { 360805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 360905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 361005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen chunk_size = ntoh64(chunk_size); 361205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen data_offset += 8; 361305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 361405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_size < 16) { 361505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 16 bytes long in this case. 361605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 361705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 361805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (chunk_size < 8) { 361905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The smallest valid chunk is 8 bytes long. 362005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 362105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 362205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunk[5]; 362405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunk_type, chunk); 3625ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset); 362605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t chunk_data_size = *offset + chunk_size - data_offset; 362805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 362905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen switch(chunk_type) { 363005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 363105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'a', 'f'): 363205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('m', 'o', 'o', 'f'): { 363305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t stop_offset = *offset + chunk_size; 363405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset = data_offset; 363505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (*offset < stop_offset) { 363605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = parseChunk(offset); 363705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 363805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 363905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 364005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 364105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 36423f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // *offset points to the box following this moof. Find the next moof from there. 36433f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen 36443f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen while (true) { 36453f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mDataSource->readAt(*offset, hdr, 8) < 8) { 36463f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 36473f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 36483f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_size = ntohl(hdr[0]); 36493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen chunk_type = ntohl(hdr[1]); 36503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 36513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen mNextMoofOffset = *offset; 36523f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen break; 36533f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 36543f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen *offset += chunk_size; 36553f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 365605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 365805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 365905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 366005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'f', 'h', 'd'): { 366105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 366205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 366305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 366405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 366605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 366705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 366805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 366905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen case FOURCC('t', 'r', 'u', 'n'): { 367005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err; 367105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId == mTrackId) { 367205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 367305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 367405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 367605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 367705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 367805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 367905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 368005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 3681ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'z'): { 3682ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3683ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 3684ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3685ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3686ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3687ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3688ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3689ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('s', 'a', 'i', 'o'): { 3690ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen status_t err; 3691ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 3692ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return err; 3693ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3694ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3695ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3696ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3697ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3698ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen case FOURCC('m', 'd', 'a', 't'): { 3699ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse DRM info if present 3700ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("MPEG4Source::parseChunk mdat"); 3701ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // if saiz/saoi was previously observed, do something with the sampleinfos 3702ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *offset += chunk_size; 3703ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen break; 3704ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3705ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 370605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen default: { 370705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *offset += chunk_size; 370805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 370905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 371005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 371105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 371205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 371305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 371484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 371584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3716ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationSizes"); 3717ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.12 3718ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3719ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt( 3720ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset, &version, sizeof(version)) 3721ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen < (ssize_t)sizeof(version)) { 3722ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3723ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3724ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3725ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version != 0) { 3726ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_UNSUPPORTED; 3727ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3728ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3729ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3730ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3731ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3732ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3733ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3734ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3735ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3736ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (flags & 1) { 3737ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3738ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3739ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3740ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3741ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoType = tmp; 3742ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3743ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3744ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3745ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3746ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentAuxInfoTypeParameter = tmp; 3747ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3748ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3749ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3750ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t defsize; 3751ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3752ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3753ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3754ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentDefaultSampleInfoSize = defsize; 3755ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3756ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3757ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t smplcnt; 3758ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &smplcnt)) { 3759ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_MALFORMED; 3760ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 376148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen mCurrentSampleInfoCount = smplcnt; 3762ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3763ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 376448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (mCurrentDefaultSampleInfoSize != 0) { 376548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 376648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return OK; 376748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 3768ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (smplcnt > mCurrentSampleInfoAllocSize) { 3769ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3770ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoAllocSize = smplcnt; 3771ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3772ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3773ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3774ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3775ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3776ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 377784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 377884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber off64_t offset, off64_t /* size */) { 3779ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen ALOGV("parseSampleAuxiliaryInformationOffsets"); 3780ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // 14496-12 8.7.13 3781ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint8_t version; 3782ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3783ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3784ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3785ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset++; 3786ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3787ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t flags; 3788ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt24(offset, &flags)) { 3789ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3790ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3791ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 3; 3792ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3793ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t entrycount; 3794ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &entrycount)) { 3795ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3796ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3797ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3798c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount == 0) { 3799c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 3800c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3801c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (entrycount > UINT32_MAX / 8) { 3802c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return ERROR_MALFORMED; 3803c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3804ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3805ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3806c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3807c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (newPtr == NULL) { 3808c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return NO_MEMORY; 3809c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3810c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia mCurrentSampleInfoOffsets = newPtr; 3811ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetsAllocSize = entrycount; 3812ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3813ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsetCount = entrycount; 3814ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3815c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia if (mCurrentSampleInfoOffsets == NULL) { 3816c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia return OK; 3817c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia } 3818c51ab7dd82bf4e24666fc72a55e03e2f530204d5Wei Jia 3819ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < entrycount; i++) { 3820ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (version == 0) { 3821ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t tmp; 3822ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &tmp)) { 3823ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3824ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3825ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3826ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 4; 3827ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } else { 3828ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint64_t tmp; 3829ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt64(offset, &tmp)) { 3830ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3831ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3832ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen mCurrentSampleInfoOffsets[i] = tmp; 3833ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen offset += 8; 3834ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3835ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3836ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3837ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen // parse clear/encrypted data 3838ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3839ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3840ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3841ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += mCurrentMoofOffset; 3842ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen int ivlength; 3843ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 384448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 3845529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen // only 0, 8 and 16 byte initialization vectors are supported 3846529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (ivlength != 0 && ivlength != 8 && ivlength != 16) { 3847529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("unsupported IV length: %d", ivlength); 3848529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen return ERROR_MALFORMED; 3849529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 385048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // read CencSampleAuxiliaryDataFormats 3851ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3852529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen if (i >= mCurrentSamples.size()) { 3853529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen ALOGW("too few samples"); 3854529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen break; 3855529c595b083f8a4c3175e2350fba5547e6008e00Marco Nelissen } 3856ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Sample *smpl = &mCurrentSamples.editItemAt(i); 3857ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3858ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memset(smpl->iv, 0, 16); 3859ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3860ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3861ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3862ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3863ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += ivlength; 3864ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 386548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 386648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize == 0) { 386748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smplinfosize = mCurrentSampleInfoSizes[i]; 3868ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 386948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smplinfosize > ivlength) { 387048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numsubsamples; 387148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3872ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return ERROR_IO; 3873ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3874ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen drmoffset += 2; 387548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen for (size_t j = 0; j < numsubsamples; j++) { 387648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint16_t numclear; 387748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen uint32_t numencrypted; 387848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt16(drmoffset, &numclear)) { 387948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 388048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 388148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 2; 388248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 388348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen return ERROR_IO; 388448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 388548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen drmoffset += 4; 388648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(numclear); 388748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(numencrypted); 3888ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 388948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } else { 389048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.add(0); 389148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.add(smpl->size); 3892ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3893ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 3894ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3895ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 3896ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 3897ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 3898ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 389905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 390005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 390205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 390305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 390505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 3906ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 390705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 390805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 390905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 391105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 391205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 391305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 391505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 391605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 391705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 391805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mLastParsedTrackId != mTrackId) { 391905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this is not the right track, skip it 392005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 392105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 392205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mFlags = flags; 392405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 392505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 392605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 392705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 392805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 392905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 393105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 393205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 393305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 393405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 393505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 393605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 393705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 393805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 393905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 394005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 394105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 394305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 394405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 394505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 394605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 394705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 394805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 394905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 395105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 395205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 395505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 395605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 395705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 395805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 395905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 396005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 396105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 396305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 396405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 396505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 396605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 396705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 396805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 396905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 397205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 397305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 397505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 397605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 397705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 397805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 397905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 398005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 398105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 398305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 398405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 398505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 398705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 398805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 398905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 399105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 399205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 399305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = 0; 399505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 399605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 399705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 399805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 399905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 400105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 8) { 400205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 400305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 400405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 400505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen enum { 400605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kDataOffsetPresent = 0x01, 400705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kFirstSampleFlagsPresent = 0x04, 400805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleDurationPresent = 0x100, 400905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleSizePresent = 0x200, 401005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleFlagsPresent = 0x400, 401105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kSampleCompositionTimeOffsetPresent = 0x800, 401205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen }; 401305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 401405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t flags; 401505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &flags)) { 401605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 401705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 401805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("fragment run flags: %08x", flags); 401905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & 0xff000000) { 402105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 402205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 402305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 402505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // These two shall not be used together. 402605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 402705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 402805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 402905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleCount; 403005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 403105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 403205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 403305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 8; 403405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 8; 403505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 403705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 403805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t firstSampleFlags = 0; 403905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kDataOffsetPresent) { 404105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 404205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 404305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 404505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t dataOffsetDelta; 404605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 404705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 404805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 404905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 405005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 405105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 405205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 405305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 405405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 405505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 405605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kFirstSampleFlagsPresent) { 405705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (size < 4) { 405805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 405905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 406205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 406305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 406505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size -= 4; 406605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 406705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 406805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 406905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 407005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 407105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t bytesPerSample = 0; 407205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 407305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 407405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 407505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 407605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 4077c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } else if (mTrex) { 4078c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen sampleDuration = mTrex->default_sample_duration; 407905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 408005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 408105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 408205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 408305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 408405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 408505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 408605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 408705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 408805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 408905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 409005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 409105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 409205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else if (mTrackFragmentHeaderInfo.mFlags 409305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 409405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 409505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 409605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 409705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 409805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 409905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 410005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bytesPerSample += 4; 410105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 410205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen sampleCtsOffset = 0; 410305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 410405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4105ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar if (size < (off64_t)(sampleCount * bytesPerSample)) { 410605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return -EINVAL; 410705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 410805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 410905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen Sample tmp; 411005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (uint32_t i = 0; i < sampleCount; ++i) { 411105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleDurationPresent) { 411205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleDuration)) { 411305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 411405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 411605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 411705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 411805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleSizePresent) { 411905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleSize)) { 412005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 412105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 412205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 412305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 412405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 412505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleFlagsPresent) { 412605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleFlags)) { 412705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 412805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 412905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 413005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 413105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 413205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (flags & kSampleCompositionTimeOffsetPresent) { 413305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 413405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 413505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 413605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset += 4; 413705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 413805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4139a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, " 4140ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen " flags 0x%08x", i + 1, 414105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset, sampleSize, sampleDuration, 414205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (flags & kFirstSampleFlagsPresent) && i == 0 414305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ? firstSampleFlags : sampleFlags); 414405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.offset = dataOffset; 414505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.size = sampleSize; 414605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen tmp.duration = sampleDuration; 4147c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen tmp.compositionOffset = sampleCtsOffset; 414805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.add(tmp); 414905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dataOffset += sampleSize; 415105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 415205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 415405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 415605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 415705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 415820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 41597b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 41607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 416120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 416220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 416320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41646064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 41656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 41666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 41676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 41686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 41696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 41706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 41716064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 41726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 41736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 41746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 41756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 41766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 41776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 41786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 41796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 41806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 41816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 41826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 418320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 418420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 41857b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 41867b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 4187dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 418820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 418905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mFirstMoofOffset > 0) { 419005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return fragmentedRead(out, options); 419105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 419205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 419320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 419420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4195abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 4196abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 419720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 4198abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 4199abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 4200abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 4201abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 4202abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 4203abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4204abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4205abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 4206abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 4207abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4208abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 4209abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 4210abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 4211abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4212abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 4213abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 4214abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 4215abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4216abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 421720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 4218abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 4219599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar seekTimeUs, 1000000, mTimescale, 4220abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 4221abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4222abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4223abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 4224abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 4225abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 4226abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 4227abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4228abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4229abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 4230abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 4231abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 4232abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 4233abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 423420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4235788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 4236788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 4237788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 4238788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 4239788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 4240788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 424120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 42425295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 42435295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 42445295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 42455295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 42465295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 42475295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 42485295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 42495295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 425005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("end of stream"); 425120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 425220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 425320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4254abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 4255abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 4256abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4257abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4258abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 4259abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 4260abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 4261abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 4262abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4263df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 4264abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 4265abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 4266abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 4267abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 4268abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 4269abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4270abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 427120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 427220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 427320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 427420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 427520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 427620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 427720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 427820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4279c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 42800024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 4281170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t cts, stts; 42828bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 4283dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 4284dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 4285dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 428620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 4288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 4289170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 429020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4291dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4292dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4293dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4294dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4295dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 4296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 4297dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 4298ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 4299dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 4300dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4301c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4302c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4303c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4304c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 43050024245e134467d120b40099da16c467dc365e76Andreas Huber } 430620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { 4308dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 4309dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 431034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 4311dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4312dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 4313dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4314dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4315dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4316dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 4317dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4318dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43197b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4320dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 4321dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 432248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 43234678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4324170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4325170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4326abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4327abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4328abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4329abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4330abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4331abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 43328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 43338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 43348bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 43358bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4336dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 4337dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4338dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 4340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 4341dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4342dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4343dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4344dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4345dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4346dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 4347dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 4348dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 4350dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4351dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 4352dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 4353dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 43555d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 43565d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 43575d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 43585d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 435929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 4360e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4361e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 4362e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 4363e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4364e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 4365e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 4366dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4367dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 43687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 43696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 4370dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 43717b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 4372dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 43736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 43746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 4375dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4376dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 4377dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 4378dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 4379dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4380dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4381dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 4382dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4383dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 4384dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 4385dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 4386dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 4387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 4388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 4389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 4392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 4393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 4395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 439620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 439720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 439820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 439920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 440020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4401dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 440220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 440320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 4405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 44076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 4408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 4409dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 4410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 4411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 4412e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 4413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 4414bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 441534fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 441634fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 441734fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 441834fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 4419bfed843041b6aaec13ee19996748a7a1476db9c8Lajos Molnar isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength); 442034fe252c89e33572d01fea981b58d7b115e76164James Dong } 4421e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 442234fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 442329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 4424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 4425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 4426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 4427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 4429dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 4430dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 4431dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4432dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 443387afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 443487afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 443587afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 443687afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size()); 443787afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen android_errorWriteLog(0x534e4554, "27208621"); 443887afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer->release(); 443987afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen mBuffer = NULL; 444087afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen return ERROR_MALFORMED; 444187afa840a40af570278e93251cfc5e55a6a3d92eMarco Nelissen } 4442dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 4443dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4444dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4445dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 4446dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 4447dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 4448dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 4449dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 4450dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 4451dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 4452dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 4453dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 4454dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 4455dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 445620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 445748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 44584678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4459170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4460170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 4461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 4463abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 4464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 4465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 4466abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 44678bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 44688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 44698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 44708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 447120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 447220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 447320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 447420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 447520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 447620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 447720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 447820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 447920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 448005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenstatus_t MPEG4Source::fragmentedRead( 448105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer **out, const ReadOptions *options) { 448205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 448305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("MPEG4Source::fragmentedRead"); 448405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 448505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mStarted); 448605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 448705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = NULL; 448805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 448905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t targetSampleTimeUs = -1; 449005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 449105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t seekTimeUs; 449205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ReadOptions::SeekMode mode; 449305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (options && options->getSeekTo(&seekTimeUs, &mode)) { 449405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 449505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int numSidxEntries = mSegments.size(); 449605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (numSidxEntries != 0) { 449705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int64_t totalTime = 0; 449805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t totalOffset = mFirstMoofOffset; 449905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen for (int i = 0; i < numSidxEntries; i++) { 450005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const SidxEntry *se = &mSegments[i]; 450105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (totalTime + se->mDurationUs > seekTimeUs) { 450205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // The requested time is somewhere in this segment 45033f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 450405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (mode == ReadOptions::SEEK_CLOSEST_SYNC && 450505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 450605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // requested next sync, or closest sync and it was closer to the end of 450705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // this segment 450805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 450905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 451005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 451105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen break; 451205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 451305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalTime += se->mDurationUs; 451405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen totalOffset += se->mSize; 451505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4516ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = totalOffset; 4517ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4518ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4519ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&totalOffset); 4520ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = totalTime * mTimescale / 1000000ll; 4521ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } else { 4522ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen // without sidx boxes, we can only seek to 0 4523ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentMoofOffset = mFirstMoofOffset; 4524ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSamples.clear(); 4525ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentSampleIndex = 0; 4526ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t tmp = mCurrentMoofOffset; 4527ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen parseChunk(&tmp); 4528ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen mCurrentTime = 0; 452905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 453005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 453105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer != NULL) { 453205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 453305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 453405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 453505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 453605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // fall through 453705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 453805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 453905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen off64_t offset = 0; 4540442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber size_t size = 0; 454105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint32_t cts = 0; 454205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool isSyncSample = false; 454305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool newBuffer = false; 454405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer == NULL) { 454505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen newBuffer = true; 454605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 454705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 45483f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen // move to next fragment if there is one 45493f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen if (mNextMoofOffset <= mCurrentMoofOffset) { 45503f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen return ERROR_END_OF_STREAM; 45513f80319d5bddfaf11a1513777561096fc1447172Marco Nelissen } 4552ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen off64_t nextMoof = mNextMoofOffset; 455305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentMoofOffset = nextMoof; 455405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSamples.clear(); 455505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentSampleIndex = 0; 455605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen parseChunk(&nextMoof); 4557ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen if (mCurrentSampleIndex >= mCurrentSamples.size()) { 4558ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen return ERROR_END_OF_STREAM; 4559ebfd32300605d67e4c45a97f4972d4b6ea268a37Marco Nelissen } 456005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 456105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 456205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 456305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen offset = smpl->offset; 456405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size = smpl->size; 4565c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen cts = mCurrentTime + smpl->compositionOffset; 456605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mCurrentTime += smpl->duration; 456705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen isSyncSample = (mCurrentSampleIndex == 0); // XXX 456805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 456905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen status_t err = mGroup->acquire_buffer(&mBuffer); 457005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 457105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (err != OK) { 457205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer == NULL); 457305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("acquire_buffer returned %d", err); 457405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return err; 457505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 4576c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen if (size > mBuffer->size()) { 4577c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen ALOGE("buffer too small: %zu > %zu", size, mBuffer->size()); 4578c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen return ERROR_BUFFER_TOO_SMALL; 4579c1a104aaad2d84a57bf5d87dd030d2bef56bf541Marco Nelissen } 458005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 458105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 458248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 458348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen const sp<MetaData> bufmeta = mBuffer->meta_data(); 458448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->clear(); 458548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen if (smpl->encryptedsizes.size()) { 458648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen // store clear/encrypted lengths in metadata 458748186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyPlainSizes, 0, 458848186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 458948186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyEncryptedSizes, 0, 459048186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 459148186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 459248186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 459348186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 459448186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 459548186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen } 459648186b6ec99aa71ec48338a55f2a2d8291681fe4Marco Nelissen 45973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { 459805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (newBuffer) { 4599da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (!isInRange((size_t)0u, mBuffer->size(), size)) { 4600da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4601da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4602da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 4603da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size); 4604da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4605da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4606da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 460705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 460805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 460905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 461005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 461105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 461205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 461305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4614da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 461505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 461605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 461705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 461805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 461905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 462005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 462105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4622170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4623170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 462405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 462505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 462605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 462705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 462805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 462905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 463005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 463105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 463205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 463305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 463405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 463505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 463605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 46373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar if (!mIsAVC && !mIsHEVC) { 463805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 463905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 464005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 464205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 464305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Each NAL unit is split up into its constituent fragments and 464505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // each one of them returned in its own buffer. 464605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer->range_length() >= mNALLengthSize); 464805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 464905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen const uint8_t *src = 465005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 465105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 465205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nal_size = parseNALSize(src); 46535d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mNALLengthSize > SIZE_MAX - nal_size) { 46545d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen ALOGE("b/24441553, b/24445122"); 46555d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen } 46565d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen 46575d101298d8b0a78a1dc5bd26dbdada411f4ecd4dMarco Nelissen if (mBuffer->range_length() - mNALLengthSize < nal_size) { 465805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGE("incomplete NAL unit."); 465905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 466005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 466105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 466205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 466305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 466405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 466505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 466605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MediaBuffer *clone = mBuffer->clone(); 466705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(clone != NULL); 466805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 466905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 467005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 467105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range( 467205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_offset() + mNALLengthSize + nal_size, 467305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->range_length() - mNALLengthSize - nal_size); 467405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 467505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (mBuffer->range_length() == 0) { 467605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 467705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 467805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 467905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 468005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = clone; 468105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 468205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 468305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 468405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ALOGV("whole NAL"); 468505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // Whole NAL units are returned but each fragment is prefixed by 468605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen // the start code (0x00 00 00 01). 468705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ssize_t num_bytes_read = 0; 468805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen int32_t drm = 0; 468905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 4690da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih void *data = NULL; 4691da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih bool isMalFormed = false; 469205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 4693da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) { 4694da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 4695da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 4696da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mBuffer->data(); 4697da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 469805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 4699da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih int32_t max_size; 4700da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mFormat == NULL 4701da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !mFormat->findInt32(kKeyMaxInputSize, &max_size) 4702da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, (size_t)max_size, size)) { 4703da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = true; 4704da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } else { 4705da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih data = mSrcBuffer; 4706da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 470705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 470805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4709da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (isMalFormed || data == NULL) { 4710da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("isMalFormed size %zu", size); 4711da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih if (mBuffer != NULL) { 4712da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer->release(); 4713da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih mBuffer = NULL; 4714da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4715da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih return ERROR_MALFORMED; 4716da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih } 4717da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih num_bytes_read = mDataSource->readAt(offset, data, size); 4718da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih 471905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (num_bytes_read < (ssize_t)size) { 472005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 472105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 472205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4723da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("i/o error"); 472405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_IO; 472505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 472605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 472705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (usesDRM) { 472805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 472905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, size); 473005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 473105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } else { 473205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen uint8_t *dstData = (uint8_t *)mBuffer->data(); 473305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t srcOffset = 0; 473405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t dstOffset = 0; 473505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 473605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen while (srcOffset < size) { 4737da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); 473805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen size_t nalLength = 0; 473905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (!isMalFormed) { 474005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 474105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += mNALLengthSize; 4742da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength) 4743da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u) 4744da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength); 474505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 474605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 474705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isMalFormed) { 4748da93c7a3bd0da4acb2d920d4549ad9e302690af1Robert Shih ALOGE("Video is malformed; nalLength %zu", nalLength); 474905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->release(); 475005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 475105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return ERROR_MALFORMED; 475205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 475305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 475405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (nalLength == 0) { 475505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen continue; 475605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 475705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 47585403587a74aee2fb57076528c3927851531c8afbMarco Nelissen if (dstOffset > SIZE_MAX - 4 || 47595403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 > SIZE_MAX - nalLength || 47605403587a74aee2fb57076528c3927851531c8afbMarco Nelissen dstOffset + 4 + nalLength > mBuffer->size()) { 47615403587a74aee2fb57076528c3927851531c8afbMarco Nelissen ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size()); 47625403587a74aee2fb57076528c3927851531c8afbMarco Nelissen android_errorWriteLog(0x534e4554, "26365349"); 47635403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer->release(); 47645403587a74aee2fb57076528c3927851531c8afbMarco Nelissen mBuffer = NULL; 47655403587a74aee2fb57076528c3927851531c8afbMarco Nelissen return ERROR_MALFORMED; 47665403587a74aee2fb57076528c3927851531c8afbMarco Nelissen } 476705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 476805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 476905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 477005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 0; 477105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstData[dstOffset++] = 1; 477205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 477305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen srcOffset += nalLength; 477405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen dstOffset += nalLength; 477505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 477605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK_EQ(srcOffset, size); 477705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen CHECK(mBuffer != NULL); 477805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->set_range(0, dstOffset); 477905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 478005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 478105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 478205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 4783170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih mBuffer->meta_data()->setInt64( 4784170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 478505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 478605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (targetSampleTimeUs >= 0) { 478705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt64( 478805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen kKeyTargetTime, targetSampleTimeUs); 478905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 479005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 479105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen if (isSyncSample) { 479205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 479305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 479405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 479505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen ++mCurrentSampleIndex; 479605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 479705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen *out = mBuffer; 479805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen mBuffer = NULL; 479905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 480005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen return OK; 480105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen } 480205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen} 480305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen 4804bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4805bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 4806bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4807bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 4808bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 4809bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 4810bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4811bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 4812bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4813bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 4814bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 4815bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 4816bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 4817bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 48181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 4819693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 482020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 482120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 482234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 482320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 482420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 482520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 482620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 482720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4828b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4829b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 48300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4831ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4832983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 483318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 48345a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 483520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 483620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 483720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 483820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 483920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 484020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 484120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 48431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 48441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 48451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 48461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 48473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'v', 'c', '1'), 48483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar FOURCC('h', 'e', 'v', '1'), 48491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 48501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 48511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 48524cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 48534cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 48544cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 48554cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 48564cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 485758fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 485858fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 485958fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 48601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 48611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 48631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 48641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 48651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 48661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 48671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 48691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 48711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 48721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 48731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 48741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 4875a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 4876a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 4877a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 48781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 4879a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4880a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4881a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 4882a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 48831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4884a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 4885a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 4886a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 4887a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 48881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4889a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 4890a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 4891a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 4892a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4893a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4894a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4895a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 4896a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 4897a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 4898a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4899a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 4900a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 49011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 49021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4904a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 4905a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 4906a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4907a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 4908a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 4909a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4910a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4911452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen 4912a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 4913a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 4914a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4915a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4916a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4917452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen // (data_offset - offset) is either 8 or 16 4918452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset); 4919452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen if (chunkDataSize < 0) { 4920452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen ALOGE("b/23540914"); 4921452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen return ERROR_MALFORMED; 4922452599f23a36207d436f7275ebc7e3ccac6ca76cMarco Nelissen } 4923a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 492405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen char chunkstring[5]; 492505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen MakeFourCCString(chunkType, chunkstring); 4926ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset); 4927a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 4928a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 4929a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4930a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 4931a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4932a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4933a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4934a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4935a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4936a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 4937a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 4938a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 4939a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 4940a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4941a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4942a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 4943a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 4944a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 4945a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4946a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4947a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4948a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 4949a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4950a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 4951a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 4952a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4953a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4954a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4955a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4956a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 4957a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 4958a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4959a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 49601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 49611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4962a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4963a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 4964a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 4965a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 4966a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4967a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 4968a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 4969a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4970a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4971a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 4972a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 49731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 4974a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4975a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 49761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4978a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 49791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 49801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 49811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 49821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 49835a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 49841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 4985a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 4986a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 4987a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4988a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 4989ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset); 4990a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 4991a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 49921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 49931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 49941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 49951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 49965a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4997a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 4998a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 49991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 50001b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 50011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 50021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 50035ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 50041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 50051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 50061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 50071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 50081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 50091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 501020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 5011