MPEG4Extractor.cpp revision 17e89b555a41aa591f1a01ecd51a7cb5a7bcfc0e
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 962a6256238d9015c42129fe43791968768fe501efaJames Dong // The video sample is not stand-compliant if it has invalid dimension. 963a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 964a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 965a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 966a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 967a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 968a6256238d9015c42129fe43791968768fe501efaJames Dong 969134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 970134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 976c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 984bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 985bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 986bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 987bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 99920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 100020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 102120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 102220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 102320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 102520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 102620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 102820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 102920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 103020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1031738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 103249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 103349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 103449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 103549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 103649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1037738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 1038738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 1039738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 1040738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1041738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 1042738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 1044113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 1045113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1046113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1047113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1048113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1049113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1050113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1051113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1052113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1053113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1054113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1055113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1056113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1057113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1058113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1059113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 106820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 107020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 107120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 107420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 10784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 10794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 10804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 10814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 10824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 10834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 10844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 10854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 10864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 10874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber *offset += chunk_size; 10884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 10894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 10904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 109120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 109220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 109320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 109420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 109520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 109620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 109820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1112c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1129ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1130ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1131ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1132ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1133ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1134ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1135ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1136ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1137ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1138ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1139ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1140ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1141ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1142ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1143ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 114520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 114620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 114920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 115020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 1151c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 115220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 115320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 115534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 115620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 115720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 115820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 116120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 116220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 116420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 116520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 116620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1167244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1168244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 116917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 117017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 117117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 117217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 117317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 117417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 117517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 117617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 117717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 117817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 117917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 118017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 118117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 118217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1183244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong LOGE("Incorrect D263 box size %lld", chunk_data_size); 1184244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1185244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1186244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1187244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1188244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1189244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1190244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1191244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1192244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1193244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1194244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong *offset += chunk_size; 1195244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1196244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1197244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 119872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 119972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 120072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1201c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1202bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1203bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1204bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 120572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 120672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 120772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 120872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 120972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 121072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 121172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1212ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1213ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1214ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1215ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1216ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1217ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1218ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 121972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 122072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1221c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 122272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 122372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 122472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 122572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 122672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 122772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 122872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1229bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1230bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1231bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1232bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 123372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 123472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 123572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 123672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 123772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 123872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 123972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 124072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 124172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 124272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 124372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 124472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 124572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 124672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 124772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 124872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 124972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 125072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 125172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 125272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 125372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 125472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 125572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 125672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 125772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 125872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 125972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 126072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 126172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 126272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 126372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 126472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 126572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1266bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1267bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 126872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 126972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 127072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 127172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 127272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 127372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 127472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 127572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 127672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 127772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 127872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 127972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 128072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1281dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1282dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1283dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1284dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1285dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1290dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1291dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1292dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1293dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1294dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 129920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1305ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1306c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 1307ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1308ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1309ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1310ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1311ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1312ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1313ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1314ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1315ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1316ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1317ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1318ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1319ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1320c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 1321ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1322ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1323ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1324ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1325ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1326ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1327ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1328ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1329ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 1330ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 1331ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1332ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 1333ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 1334ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 1335ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 1336ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 1337ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1338ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)version, 0u); 1339ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1340ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 1341ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 1342ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 1343ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 1344ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1345ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1346ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1347ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1348ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 1349ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1350ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1351ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1352ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1353ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1354ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1355ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1356ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1357ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("x' = %.2f * x + %.2f * y + %.2f", 1358ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1359ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("y' = %.2f * x + %.2f * y + %.2f", 1360ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1361ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1362ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1363ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 1364ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1365ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 1366ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1367ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 1368ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1369ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1370ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 1371ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1372ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 1373ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1374ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 1375ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1376ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGW("We only support 0,90,180,270 degree rotation matrices"); 1377ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1378ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1379ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1380ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 1381ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1382ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1383ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1384b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 1385b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 1386ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 1387ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 1388b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 1389b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 1390ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1391ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 1392ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 1393ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1394c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 139572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 139672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 139772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 139872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 139972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 140072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 140172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 140272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 140372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 140472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 140572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 140672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 140772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 140872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 140972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 141072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 141172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 141272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 141372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 141472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 141572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 141672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 141772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 141872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 141972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 142072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 142172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 142266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 142366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 142466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 142566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 142666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 142772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 142872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 142972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 143072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 143172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 143272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 143372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 143472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 143572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 143672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 143772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 143872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 143972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 144072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 144172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 144372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 144472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 144572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 144672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 144872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 144972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 145072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 145172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 145226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 145326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 145426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 145526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 145626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 145711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 145811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 145911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 146011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 146111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 146211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 146311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 146411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 146511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 146611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 146711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 146872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 146972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 147072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 147172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 147272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 147372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 147472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 147572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 147672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 147772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 147872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 147926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 148026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 148126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (size == 14 && flags == 0) { 148226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 148326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(tmp, "%d/%d", 148426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 148526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 148626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 148726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 148826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 148926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 149026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 149172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 149272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 149372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 149472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 149572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 149672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 149772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 149872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 149972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 150072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 150172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 150226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 150326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 150426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 150526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 150626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 150726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 150826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 150926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 151026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 151172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 151226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 151372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 151472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 151526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 151626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 151726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 151826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 151926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 152026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 152172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 152272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 152372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 152472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 152572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 152672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 152772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 152872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 152972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 153072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 153172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 153272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 153372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 153472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 153572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 153720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 153820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 154020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 154120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 154220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 154320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 154420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 154620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 154720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 154820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 154920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 155020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 155120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1552371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1553371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1554371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1555371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 155748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 155820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 155920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1560bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 1561bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 1562bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 1563bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1564bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1565bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 1566bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 1567bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 1568bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1569bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1570bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 1571bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1572bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1573bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1574bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1575bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1576bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 1577bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1578bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1579bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1580bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1581bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 1582bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 1583bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1584ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1585ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1586ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 158781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 158881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 158981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 159081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 159181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 159281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 159381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 159481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 159581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 159681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 159781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 159881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1599ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1600ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1601ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1602ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1603ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1604ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1605ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1606ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1607ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1608ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1609ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1610ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1611a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 1612a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 1613a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1614a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 1615a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1616a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 1617a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 1618a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1619ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1620ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1621ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1622ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1623ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1624ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1625ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1626ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1627ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1628ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1629ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1630ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1631ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1632ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1633ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1634ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1635ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1636ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1637ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1638ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1639ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1640ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1641ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1642ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1643ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 16443c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber static uint32_t kSamplingRate[] = { 16453c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16463c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 16000, 12000, 11025, 8000, 7350 16473c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber }; 1648ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1649ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1650ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1651ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1652ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1653ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1654ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1655ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1656ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1657ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1658ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1659ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1660ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1661ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1662ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1663ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1664ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 1665ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1666ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1667ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1668ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1669ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1670ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1671ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1672ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1673ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1674ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 1675ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1676ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1677ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1678ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1679ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1680ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1681ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1682ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1683ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 168420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 168520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 168620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 168720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 168948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 169120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 169220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 169348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 169420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 169520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 169620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 16976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 169820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 169920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 170020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1701dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 17020024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 170320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 170420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1705dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 170620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 170718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 17086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 17106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 17116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 17126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 17136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 17146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 17166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 1718ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 17196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 17216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 17226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 17327b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 17337b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1734dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 173520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1737dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 173820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1739dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 174020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1741dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 174220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 174320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 174420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 174520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1746738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1747738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 174820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1749738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 17500024245e134467d120b40099da16c467dc365e76Andreas Huber 17510024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 175220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 175320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 175420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 175520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 175620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 175720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 175820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 17597b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 17607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1761dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 176220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 176320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 176420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 176520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 176620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 176720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17680024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 17690024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 17700024245e134467d120b40099da16c467dc365e76Andreas Huber 177120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 177220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 177320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 177520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 177620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 177820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 177920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 178020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 17817b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 17827b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 178320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 178420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 178520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 17876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 17886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 17896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 17906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 17916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 17926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 17936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 17946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 17956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 17966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 17976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 17996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 18006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 18016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 18026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 18036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 18046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 18077b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 18087b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1809dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 181020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 181220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1813abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 1814abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 181520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1816abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1817abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 1818abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 1819abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 1820abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 1821abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1822abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1823abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 1824abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 1825abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1826abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 1827abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 1828abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 1829abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1830abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 1831abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 1832abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1833abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1834abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 183520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 1836abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 183720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 1838abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 1839abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1840abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1841abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 1842abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 1843abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 1844abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1845abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1846abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1847abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 1848abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 1849abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 1850abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 1851abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 185220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 185320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 18545295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 18555295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 18565295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 18575295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 18585295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 18595295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 18605295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 18615295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 186220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 186320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 186420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1865abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 1866ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((status_t)OK, mSampleTable->getMetaDataForSample( 1867abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, NULL, NULL, &sampleTime)); 1868abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1869abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1870abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 1871abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1872abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1873abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 1874abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 1875abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 1876abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 1877abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1878abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 1879abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 1880abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 1881abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 1882abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 1883abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 1884abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1885abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 188620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 188720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 188820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 188920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 189020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 189120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 189220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 189320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1894c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 18950024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1896dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 18978bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 1898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 190120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1902c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1903c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 19048bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample); 190520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1909dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1910dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1911c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1912dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1913ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 1914dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1915dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 19160024245e134467d120b40099da16c467dc365e76Andreas Huber } 191720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1918dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1919dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1920dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 192134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1922dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1924dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1925dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1926dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1927dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1928dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1929dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 19307b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1931dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1932dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 193348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 193448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1935abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1936abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1937abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1938abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1939abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1940abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 19418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 19428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 19438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 19448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 1945dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1946dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1948dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1949dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1950dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1951dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1952dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1953dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1954dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1955dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1956dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1957dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 19586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1959dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1960dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1961dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1962dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 19636064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1964e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1965e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1966e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1967e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1968e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1969e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1970e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1971e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1972dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1973dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 19747b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 19756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1976dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 19777b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1978dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 19796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 19806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1981dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1982dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1983dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1984dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1985dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1986dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1987dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1988dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1989dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1990dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1991dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1992dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1993dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 1994dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 1995dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 1996dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 1997dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 1998dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 1999dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 2000dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 2001dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 200220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 200320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 200420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 200520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 200620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2007dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 200820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 200920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2010dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 2011dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 2012dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 20136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 2014dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 2015dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 2016dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 2017dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 2018e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2019dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 2020dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(srcOffset + mNALLengthSize <= size); 2021dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 2022dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += mNALLengthSize; 2023e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2024dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (srcOffset + nalLength > size) { 2025dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 2026dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 2027dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2028dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 2029dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2030dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2031dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 2032dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 2033dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2034dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2035dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 2036dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2037dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2038dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2039dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2040dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 2041dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 2042dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 2043dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 2044dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2045dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 2046dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 2047dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 2048dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2049dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 205020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 205148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 205248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 2053abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2054abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 2055abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 2056abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 2057abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2058abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 20598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 20608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 20618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 20628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 206320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 206420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 206520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 206620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 206720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 206820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 206920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 207020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 207120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 2073693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 207420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 207520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 207634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 207720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 207820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 207920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 208020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 208120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2082b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2083b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 20840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2085ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2086983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 208718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 20885a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 208920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 209020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 209120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 209220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 209320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 209420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 209520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 20971b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 20981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 20991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 21001b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 21011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 21021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 21031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 21041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 21051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 21071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 21081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 21091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 21101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 21111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 21151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 21161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 21181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 21191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 21201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 21211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t header[12]; 21221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(0, header, 12) != 12 21231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber || memcmp("ftyp", &header[4], 4)) { 21241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 21251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t atomSize = U32_AT(&header[0]); 21281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 21291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 21301b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21311b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21321b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber bool success = false; 21331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 21341b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 21351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } else { 21361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 21371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 21381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t tmp[4]; 21391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 21401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 21411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 21441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 21451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 21461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (!success) { 21511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 21521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 21555a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 21561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 21581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 21591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 21615a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 21625a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 21631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 21641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 21651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 21681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 21691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 21701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 21711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 21721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 21731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 21741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 217520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 217620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2177