MPEG4Extractor.cpp revision e071b055cee301d71335519601474c62b10af411
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 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 32ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#include "include/ESDS.h" 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 66693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 820024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 830024245e134467d120b40099da16c467dc365e76Andreas Huber 846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 101c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 102c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 10350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 105c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 10650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 114c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 11550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 149c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 15050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 161c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 169c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 24118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 243371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 245371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 250e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 251e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 25218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 258dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 263693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 2667be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 269dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 270dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 271dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 283dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 284dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 285dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf->IPMPData; 288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 290dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 291dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 29772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2987be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 2997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 30072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 3017be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 3027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 336371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 338371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 339371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 350c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 351c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 352c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 368c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3727be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 37472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 37572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 37672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 37772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 37872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 37972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangvoid MPEG4Extractor::setDrmFlag(bool flag) { 387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm = flag; 388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 400dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 407dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 409c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongint32_t readSize(off64_t offset, 410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 412dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 414dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 415dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 416dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 417dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 418dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 419dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 420dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 421dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 422dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 423dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 429c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { 430dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 431dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 432dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 433dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 434dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 435dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 436dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 437dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 438dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 439dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 440dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 441dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 442dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 443dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 444dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 445dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t classSize = size; 446dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 447dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 448dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 449dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 450dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 451dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 452dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 453dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 454dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 455dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 456dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 457dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 458dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 459dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 460dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 461dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 462dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 463dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 464dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 465dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 466dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 467dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 468dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 469dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 470dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 471dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 472dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 473dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 474dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 475dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 476dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 477dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 478dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 479dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 480dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 481dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 482dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 483dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 484dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 485dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 486dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 487dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 488dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 489dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 490dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 491dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 492dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 493dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 494dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 495dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 496dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 497dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 498dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 499dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 500dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 501dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 502dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 503dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 504dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 505dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 506dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang classSize = size; 507dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 508dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 509dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 510dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 511dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 512dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 513dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 514dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 515dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 516dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 517dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 518dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 519dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 520dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 521dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 522dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 523dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 524dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 525dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 526dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 527dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 528dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 529dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 530dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 531dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 532dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 533dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 534dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 535dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 536dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 537dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 538dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 539dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 540dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPData = new char[sinf->len]; 541dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 542dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { 543dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 544dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 545dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 56772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 56872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 56972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 57072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 57172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 57372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 57472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 57572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 57772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 57872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 58072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 58172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 58272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 58372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 58472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 58572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 58672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 58772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 58872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 58972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 59072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 59272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 59372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 59472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 59672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 59772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 59972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 60072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 601c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 60334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 608c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 61134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 61671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 61771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 61871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 61971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 62071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 62171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 62271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 62371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 635ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 636ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 637ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 638ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 639ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 640ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 641ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 643ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 644ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 64872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 649c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 65272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 653c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 65472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 65572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 65672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 65772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 65872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 65972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 66072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 661bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 662bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 663bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 664bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 66572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 66672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 66772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 66872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 68072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 68172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 68350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 68450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 68550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 686b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 687b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 688b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 68950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 69050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 69150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 69250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 69350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 69450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 69550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 6961edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 6971edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 69850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 69950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 7006f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 701bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 7026f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 7036f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 704bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 705bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 706bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 707bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 708bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 709bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 710bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 711bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 712bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 713bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 714bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 7156f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 716bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 717bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 718bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 719bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 720c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 729bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 730bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 731bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 732bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 7336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 7346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 7356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 7366f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7376f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 7386f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 7396f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 7406f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 7416f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 7426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 7436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7446f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 7456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 7466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 7476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 7506f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7516f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 752bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 753bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 754bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 756bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 757bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 760dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 761dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 762dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 763dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 764dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 771ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 772ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 773ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 78734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 793c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 80434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 81434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 82234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 83048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 843c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 844bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 845bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 846bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 84734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 8616f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 8626f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack->skipTrack = true; 8636f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber *offset += chunk_size; 8646f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber break; 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 867c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 875bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 876bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 877bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 878bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 884371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 88920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 89020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 89820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 90181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 90281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 90318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 90481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber FourCC2MIME(chunk_type))) { 90581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR NB audio is always mono, 8kHz 90681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber num_channels = 1; 90781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 8000; 90881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 90918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 91081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR WB audio is always mono, 16kHz 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 91281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 16000; 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#if 0 91681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 91781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 91881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#endif 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 924c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 932bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 933bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 934bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 935bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 94020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 941e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 942e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 94320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 94420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 9457be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 9467be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 94720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 94820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 94920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 962134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 963134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 969c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 977bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 978bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 979bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 980bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 100020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 100120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 102120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 102220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 102320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1024738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 102549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 102649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 102749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 102849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 102949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1030738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 1031738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 1032738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 1033738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1034738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 1035738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 1036738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 103720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 103820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 103920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 104020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 104220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 104520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 104620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 104820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 105320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 105620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 107020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 107120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1076c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 107820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 108120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 108220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 108320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 108620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 108720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 108820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 109120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 109220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1093ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1094ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1095ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1096ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1097ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1098ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1099ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1100ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1101ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1102ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1103ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1104ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1105ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1106ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1107ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 1115c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 111620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 113272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 113372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1134c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1135bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1136bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1137bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 113872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 113972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 114072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 114172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 114272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 114372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 114472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1145ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1146ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1147ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1148ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1149ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1150ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1151ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 115272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 115372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1154c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 115572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 115672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 115772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 115872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 115972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 116072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 116172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1162bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1163bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1164bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1165bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 116672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 116772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 116872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 116972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 117072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 117172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 117272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 117372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 117472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 117572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 117672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 117772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 117872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 117972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 118072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 118172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 118272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 118372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 118472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 118572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 118672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 118772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 118872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 118972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 119072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 119172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 119272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 119372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 119472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 119572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 119672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 119772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 119872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1199bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1200bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 120172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 120272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 120372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 120472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 120572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 120672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 120772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 120872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 120972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 121072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 121172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 121272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 121372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1214dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1215dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1216dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1217dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1218dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1219dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1220dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1221dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1222dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1223dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1224dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1225dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1226dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1227dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 122920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1238ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1239c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 1240ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1241ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1242ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1243ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1244ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1245ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1246ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1247ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1248ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1249ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1250ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1251ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1252ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1253c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 1254ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1255ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1256ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1257ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1258ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1259ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1260ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1261ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1262ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 1263ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 1264ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1265ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 1266ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 1267ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 1268ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 1269ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 1270ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1271ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)version, 0u); 1272ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1273ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 1274ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 1275ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 1276ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 1277ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1278ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1279ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1280ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1281ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 1282ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1283ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1284ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1285ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1286ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1287ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1288ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1289ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1290ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("x' = %.2f * x + %.2f * y + %.2f", 1291ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1292ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("y' = %.2f * x + %.2f * y + %.2f", 1293ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1294ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1295ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1296ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 1297ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1298ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 1299ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1300ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 1301ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1302ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1303ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 1304ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1305ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 1306ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1307ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 1308ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1309ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGW("We only support 0,90,180,270 degree rotation matrices"); 1310ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1311ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1312ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1313ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 1314ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1315ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1316ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1317ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1318ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 1319ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 1320ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1321ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1322ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 1323ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 1324ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1325c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 132672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 132772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 132872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 132972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 133172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 133272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 133372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 133472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 133572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 133772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 133872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 134072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 134172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 134272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 134372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 134472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 134572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 134672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 134772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 134872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 134972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 135072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 135172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 135272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 135366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 135466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 135566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 135666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 135766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 135872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 135972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 136072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 136172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 136272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 136372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 136472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 136572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 136672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 136772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 136872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 136972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 137072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 137172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 137272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 137372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 137472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 137572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 137672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 137772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 137872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 137972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 138072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 138172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 138272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 138326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 138426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 138526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 138626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 138726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 138872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 138972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 139072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 139172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 139272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 139372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 139472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 139572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 139672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 139772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 139872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 139926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 140026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 140126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (size == 14 && flags == 0) { 140226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 140326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(tmp, "%d/%d", 140426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 140526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 140626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 140726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 140826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 140926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 141026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 141172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 141272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 141372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 141472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 141572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 141672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 141772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 141872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 141972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 142072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 142172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 142226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 142326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 142426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 142526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 142626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 142726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 142826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 142926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 143026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 143172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 143226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 143372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 143472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 143526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 143626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 143726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 143826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 143926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 144026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 144172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 144372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 144472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 144572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 144672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 144772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 145072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 145172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 145272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 145372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 145472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 145572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1456693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 145720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1465693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 146620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 146920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1472371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1473371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1474371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1475371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 147748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 147820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 147920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1480bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 1481bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 1482bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 1483bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1484bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1485bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 1486bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 1487bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 1488bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1489bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1490bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 1491bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1492bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1493bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1494bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1495bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1496bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 1497bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1498bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1499bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1500bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1501bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 1502bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 1503bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1504ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1505ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1506ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 150781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 150881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 150981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 151081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 151181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 151281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 151381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 151481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 151581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 151681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 151781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 151881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1519ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1520ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1521ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1522ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1523ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1524ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1525ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1526ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1527ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1528ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1529ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1530ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1531a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 1532a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 1533a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1534a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 1535a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1536a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 1537a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 1538a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1539ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1540ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1541ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1542ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1543ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1544ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1545ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1546ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1547ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1548ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1549ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1550ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1551ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1552ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1553ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1554ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1555ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1556ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1557ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1558ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1559ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1560ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1561ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1562ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1563ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 15643c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber static uint32_t kSamplingRate[] = { 15653c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 15663c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 16000, 12000, 11025, 8000, 7350 15673c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber }; 1568ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1569ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1570ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1571ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1572ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1573ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1574ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1575ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1576ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1577ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1578ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1579ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1580ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1581ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1582ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1583ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1584ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 1585ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1586ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1587ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1588ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1589ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1590ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1591ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1592ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1593ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1594ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 1595ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1596ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1597ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1598ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1599ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1600ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1601ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1602ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1603ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 160420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 160520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 160620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 160720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 160948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 161120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 161220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 161348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 161420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 161520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 16176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 161820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1621dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 16220024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 162320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 162420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1625dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 162620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 162718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 16286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 16306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 16316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 16326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 16336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 16346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 16366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 1638ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 16396064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 16416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 16426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 164320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 164420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 164620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 164820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 164920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 165020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 16527b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 16537b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1654dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 165520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1657dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 165820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1659dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 166020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1661dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 166220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 166520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1666738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1667738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1669738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 16700024245e134467d120b40099da16c467dc365e76Andreas Huber 16710024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 167420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 167620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 167720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 16797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 16807b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1681dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 168220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 168320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 168420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 168520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 168620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 168720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16880024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 16890024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 16900024245e134467d120b40099da16c467dc365e76Andreas Huber 169120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 169220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 169320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 169420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 169520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 169620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 169720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 169820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 169920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 170020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 17017b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 17027b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 170320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 170420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 170520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 17076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 17086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 17096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 17106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 17116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 17126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 17136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 17146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 17156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 17166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 17176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 17196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 17206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 17216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 17236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 17246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 172520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 17277b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 17287b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1729dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 173220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1733abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 1734abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 173520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1736abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1737abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 1738abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 1739abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 1740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 1741abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1742abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1743abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 1744abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 1745abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1746abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 1747abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 1748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 1749abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1750abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 1751abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 1752abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1753abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1754abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 175520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 1756abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 175720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 1758abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 1759abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1760abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1761abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 1762abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 1763abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 1764abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1765abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1766abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1767abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 1768abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 1769abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 1770abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 1771abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 177220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 17745295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 17755295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 17765295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 17775295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 17785295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 17795295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 17805295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 17815295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 178220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 178320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 178420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1785abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 1786ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((status_t)OK, mSampleTable->getMetaDataForSample( 1787abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, NULL, NULL, &sampleTime)); 1788abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1789abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1790abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 1791abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1792abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1793abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 1794abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 1795abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 1796abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 1797abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1798abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 1799abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 1800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 1801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 1802abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 1803abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 1804abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1805abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 180820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 181220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1814c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 18150024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 18178bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 1818dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1819dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1820dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 182120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1822c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1823c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 18248bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample); 182520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1826dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1827dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1828dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1829dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1830dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1831c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1832dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1833ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 1834dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1835dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 18360024245e134467d120b40099da16c467dc365e76Andreas Huber } 183720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1839dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1840dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 184134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1842dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1846dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1847dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1849dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18507b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1851dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1852dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 185348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 185448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1855abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1856abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1857abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1858abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1859abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1860abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 18618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 18628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 18638bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 18648bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 1865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1866dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1867dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1868dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1871dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1873dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1874dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1875dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1876dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1877dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1879dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1880dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1881dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1882dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1884e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1885e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1886e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1887e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1888e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1889e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1890e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1891e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1893dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 18947b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 18956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1896dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18977b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 18996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 19006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1904dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1909dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1910dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1911dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1912dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1913dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 1914dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 1915dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 1916dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 1917dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 1918dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 1919dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1920dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 1921dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 192220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 192320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 192420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 192520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 192620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1927dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 192820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 192920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1930dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 1931dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 1932dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 19336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1934dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1935dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 1936dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 1937dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 1938e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1939dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 1940dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(srcOffset + mNALLengthSize <= size); 1941dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1942dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += mNALLengthSize; 1943e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1944dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (srcOffset + nalLength > size) { 1945dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 1946dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 1947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1948dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1949dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1950dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1951dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 1952dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 1953dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1954dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1955dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 1956dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1957dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 1958dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 1959dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 1960dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 1961dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1962dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 1963dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 1964dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1965dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 1966dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 1967dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 1968dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1969dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 197020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 197148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 197248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1973abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1974abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1975abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1976abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1977abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1978abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 19798bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 19808bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 19818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 19828bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 198320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 198420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 198520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 198620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 198720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 198820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 198920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 199020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 199120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 1993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 199420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 199520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 199634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 199720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 199820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 199920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 200020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 200120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2002b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2003b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 20040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2005ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2006983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 200718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 20085a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 200920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 201020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 201120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 201220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 201320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 201420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 201520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 20171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 20181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 20191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 20201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 20211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 20221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 20231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 20241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 20251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 20271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 20281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 20291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 20301b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20311b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20321b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20341b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 20361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 20381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 20391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 20401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 20411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t header[12]; 20421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(0, header, 12) != 12 20431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber || memcmp("ftyp", &header[4], 4)) { 20441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t atomSize = U32_AT(&header[0]); 20481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 20491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber bool success = false; 20531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 20541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 20551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } else { 20561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 20571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 20581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t tmp[4]; 20591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 20601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 20641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 20651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 20661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (!success) { 20711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 20755a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 20761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 20791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 20815a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 20825a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 20831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 20841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 20881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 20891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 20941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 209520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 209620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2097