MPEG4Extractor.cpp revision 788a07fc61bad7ea2f0e3cca3f126b52a9bab376
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" 227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include "include/ESDS.h" 23965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include "timedtext/TimedTextPlayer.h" 2489e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 50693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 62693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 657b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 67693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 830024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 840024245e134467d120b40099da16c467dc365e76Andreas Huber 856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 102c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 103c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 106c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 115c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 150c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 162c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 170c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 24218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 244371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 246371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 251e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 252e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 25318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 259dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 264693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 266bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 2677be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 270dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 271dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 272dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 284dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 285dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf->IPMPData; 289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 290dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 291dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 292dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 29872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 3007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 30172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 3027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 3037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 338371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 339371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 340371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 351c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 352c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 353c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 365bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 366bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 369c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3737be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 374bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 37572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 37672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 37772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 37872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 37972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 3814678a6dc5f09008481524949a9667af5a6190374Andreas Huber mInitCheck = OK; 382bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 383bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 386bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 387bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 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') 652515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 65372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 654c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 65572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 65672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 65772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 65872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 65972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 66072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 66172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 662bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 663bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 664bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 665bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 66672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 66772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 66872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 66972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 68172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 68272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 68450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 68550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 68650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 687b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 688b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 689b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 69050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 69150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 69250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 69350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 69450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 69550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 69650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 6971edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 6981edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 69950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 70050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 7016f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 702bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 7036f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 7046f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 705bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 706bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 707bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 708bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 709bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 710bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 711bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 712bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 713bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 714bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 715bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 7166f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 717bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 718bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 719bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 720bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 721c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 730bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 731bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 732bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 733bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 7346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 7356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 7366f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 7376f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7386f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 7396f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 7406f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 7416f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 7426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 7436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 7446f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 7466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 7476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 7486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7506f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 7516f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7526f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 753bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 754bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 756bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 757bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 758bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 759bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 761dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 762dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 763dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 764dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 765dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 772ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 773ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 774ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 78834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 794c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 80534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 81534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 82334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 83148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 8347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 8357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 8367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 8377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 8387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 8397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 8407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 8417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 8427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 8437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 8447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 8457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 8467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 8477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 8487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 8497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 8507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 8517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 8527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 8537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 8547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 8557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 8567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 8577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 8587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 8597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 86120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 871c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 872bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 873bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 874bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 87534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 8883b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 8893b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 8903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 8913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 8923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 8933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { 8943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 8953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 8963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 8973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 8983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 901c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 909bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 910bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 911bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 912bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 91420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 918371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 93581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 93681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 93718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 93881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber FourCC2MIME(chunk_type))) { 93981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR NB audio is always mono, 8kHz 94081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber num_channels = 1; 94181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 8000; 94281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 94318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 94481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR WB audio is always mono, 16kHz 94520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 94681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 16000; 94720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 94820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 94981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#if 0 95081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 95181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 95281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#endif 95320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 958c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 966bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 967bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 968bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 969bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 975e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 976e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 9797be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 9807be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 996a6256238d9015c42129fe43791968768fe501efaJames Dong // The video sample is not stand-compliant if it has invalid dimension. 997a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 998a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 999a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1000a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1001a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1002a6256238d9015c42129fe43791968768fe501efaJames Dong 1003134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1004134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1010c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1018bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1019bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1020bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1021bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 102220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 102320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 102620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 102720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 102820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 102920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 103020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 103120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 103320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 103420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 103520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 103720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 103820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 103920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 104120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 104220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 104520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 104720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 104820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 105620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1065738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 106649110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 106749110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 106849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 106949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 107049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1071738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 1072738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 1073738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 1074738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1075738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 1076738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 1078113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 1079113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1080113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1081113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1082113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1083113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1084113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1085113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1086113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1087113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1088113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1089113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1090113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1091113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1092113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1093113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 109420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 109520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 109620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 109820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 110020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 110120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 11124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 11134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 11144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 11154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 11164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 11174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 11184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 11194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 11204931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 11214931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber *offset += chunk_size; 11224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 11234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 11244931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 113220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 113320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 113620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 113720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 114020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 114120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 114220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 114320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1146c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 114720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 114820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 115034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 115120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 115220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 115320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 115520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 115620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 115720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 115820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 115920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 116120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 116220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1163ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1164ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1165ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1166ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1167ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1168ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1169ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1170ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1171ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1172ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1173ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1174ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1175ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1176ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1177ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 117920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 118320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 118420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 1185c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 118720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 119620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1201244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1202244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 120317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 120417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 120517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 120617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 120717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 120817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 120917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 121017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 121117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 121217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 121317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 121417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 121517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 121617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 1217244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong LOGE("Incorrect D263 box size %lld", chunk_data_size); 1218244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1219244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1220244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1221244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1222244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1223244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1224244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1225244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1226244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1227244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1228244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong *offset += chunk_size; 1229244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1230244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1231244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 123272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 123372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 123472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1235c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1236bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1237bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1238bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 123972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 124072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 124172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 124272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 124372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 124472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 124572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1246ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1247ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1248ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1249ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1250ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1251ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1252ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 125372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 125472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1255c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 125672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 125772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 125872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 125972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 126072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 126172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 126272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1263bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1264bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1265bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1266bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 126772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 126872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 126972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 127072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 127172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 127272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 127372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 127472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 127572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 127672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 127772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 127872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 127972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 128072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 128172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 128272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 128372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 128472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 128572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 128672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 128772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 128872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 128972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 129072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 129172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 129272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 129372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 129472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 129572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 129672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 129772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 129872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 129972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1300bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1301bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 130272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 130372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 130472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 130572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 130672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 130772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 130872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 130972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 131072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 131172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 131272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 131372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 131472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1315dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1316dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1317dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1318dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1319dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1320dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1321dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1322dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1323dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1324dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1325dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1326dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1327dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1328dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 13293b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 13303b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 13313b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 13323b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 13333b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 13343b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 13353b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13363b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13373b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 13383b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 13393b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // shall be 'text' 13403b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (type == FOURCC('t', 'e', 'x', 't')) { 13413b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 13423b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13433b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13443b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 13453b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 13463b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13473b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 13497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 13503b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 13513b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 13523b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 13533b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 13543b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 13553b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 13563b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13573b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13583b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint8_t *buffer = new uint8_t[size + chunk_size]; 13593b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13603b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 13613b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 13623b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13633b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13643b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 13653b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 13663b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 13673b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 13683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 13703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 13733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 13743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 13767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 13777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 13787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 13797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 13807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 1381515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 1382515e855eae78aa495da58356486aaa666cb57fd1James Dong { 1383515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 1384515e855eae78aa495da58356486aaa666cb57fd1James Dong LOGV("chunk_data_size = %lld and data_offset = %lld", 1385515e855eae78aa495da58356486aaa666cb57fd1James Dong chunk_data_size, data_offset); 1386515e855eae78aa495da58356486aaa666cb57fd1James Dong uint8_t *buffer = new uint8_t[chunk_data_size + 1]; 1387515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 1388515e855eae78aa495da58356486aaa666cb57fd1James Dong data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) { 1389515e855eae78aa495da58356486aaa666cb57fd1James Dong delete[] buffer; 1390515e855eae78aa495da58356486aaa666cb57fd1James Dong buffer = NULL; 1391515e855eae78aa495da58356486aaa666cb57fd1James Dong 1392515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 1393515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1394515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 1395515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 1396515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 1397515e855eae78aa495da58356486aaa666cb57fd1James Dong buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1398515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1399515e855eae78aa495da58356486aaa666cb57fd1James Dong 1400515e855eae78aa495da58356486aaa666cb57fd1James Dong *offset += chunk_size; 1401515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 1402515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1403515e855eae78aa495da58356486aaa666cb57fd1James Dong 140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 140620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 141020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 141120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 141220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1414ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1415c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 1416ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1417ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1418ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1419ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1420ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1421ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1422ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1423ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1424ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1425ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1426ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1427ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1428ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1429c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 1430ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1431ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1432ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1433ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1434ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1435ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1436ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1437ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1438ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 1439ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 1440ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1441ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 1442ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 1443ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 1444ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 1445ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 1446ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1447ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)version, 0u); 1448ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1449ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 1450ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 1451ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 1452ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 1453ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1454ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1455ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1456ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1457ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 1458ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1459ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1460ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1461ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1462ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1463ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1464ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1465ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1466ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("x' = %.2f * x + %.2f * y + %.2f", 1467ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1468ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("y' = %.2f * x + %.2f * y + %.2f", 1469ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1470ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1471ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1472ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 1473ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1474ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 1475ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1476ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 1477ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1478ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1479ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 1480ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1481ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 1482ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1483ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 1484ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1485ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGW("We only support 0,90,180,270 degree rotation matrices"); 1486ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1487ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1488ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1489ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 1490ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1491ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1492ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1493b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 1494b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 1495ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 1496ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 1497b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 1498b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 1499ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1500ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 1501ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 1502ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1503c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 150472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 150572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 150672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 150772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 150872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 150972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 151072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 151172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 151272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 151372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 151472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 151572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 151672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 151772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 151872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 151972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 152072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 152172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 152272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 152372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 152472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 152572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 152672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 152772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 152872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 152972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 153072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 153166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 153266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 153366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 153466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 153566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 153672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 153772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 153872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 153972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 154072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 154172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 154272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 154372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 154472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 154572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 154672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 154772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 154872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 154972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 155072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 155172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 155272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 155372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 155472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 155572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 155672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 155772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 155872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 155972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 156072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 156126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 156226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 156326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 156426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 156526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 156611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 156711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 156811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 156911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 157011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 157111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 157211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 157311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 157411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 157511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 157611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 157772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 157872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 157972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 158072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 158172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 158272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 158372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 158472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 158572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 158672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 158772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 158826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 158926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 159026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (size == 14 && flags == 0) { 159126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 159226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(tmp, "%d/%d", 159326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 159426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 159526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 159626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 159726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 159826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 159926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 160072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 160172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 160272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 160372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 160472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 160572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 160672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 160772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 160872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 160972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 161072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 161126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 161226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 161326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 161426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 161526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 161626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 161726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 161826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 161926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 162072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 162126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 162272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 162372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 162426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 162526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 162626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 162726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 162826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 162926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 163072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 163172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 163272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 163372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 163472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 163572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 163672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 163772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 163872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 163972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 164072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 164172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 164272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 164372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 164472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 164620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 164920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 165020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 165220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 165320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 165520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 165820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 165920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1661371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1662371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1663371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1664371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 166648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 166720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1669bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 1670bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 1671bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 1672bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1673bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1674bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 1675bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 1676bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 1677bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1678bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1679bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 1680bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1681bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1682bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1683bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1684bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1685bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 1686bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1687bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1688bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1689bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1690169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber if (!track->sampleTable->isValid()) { 1691169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 1692169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 1693169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 1694169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 1695bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 1696bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 1697bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1698ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1699ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1700ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 170181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 170281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 170381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 170481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 170581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 170681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 170781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 170881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 170981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 171081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 171181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 171281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1713633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 1714633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 1715633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 1716633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 1717633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong LOGE("MP3 track in MP4/3GPP file is not supported"); 1718633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 1719633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 1720633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 1721ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1722ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1723ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1724ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1725ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1726ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1727ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1728ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1729ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1730ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1731ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1732ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1733a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 1734a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 1735a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1736a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 1737a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1738a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 1739a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 1740a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1741ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1742ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1743ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1744ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1745ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1746ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1747ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1748ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1749ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1750ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1751ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1752ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1753ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1754ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1755ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1756ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1757ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1758ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1759ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1760ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1761ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1762ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1763ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1764ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1765ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 17663c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber static uint32_t kSamplingRate[] = { 17673c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 17683c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 16000, 12000, 11025, 8000, 7350 17693c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber }; 1770ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1771ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1772ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1773ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1774ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1775ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1776ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1777ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1778ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1779ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1780ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1781ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1782ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1783ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1784ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1785ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1786ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 1787ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1788ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1789ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1790ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1791ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1792ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1793ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1794ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1795ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1796ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 1797ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1798ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1799ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1800ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1801ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1802ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1803ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1804ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1805ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 180820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1810693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 181148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1812693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 181320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 181420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 181548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 181620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 181720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 181820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 18196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 182020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 182120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 182220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1823dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 18240024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 182520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 182620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1827dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 182820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 182918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 18306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 18316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 18326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 18336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 18346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 18356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 18366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 18376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 18386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 18396064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 1840ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 18416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 18426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 18436064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 18446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 184520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 184620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 184720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 184820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 184920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 185020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 185120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 185220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 185320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 18547b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 18557b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1856dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 185720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 185820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1859dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 186020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1861dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 186220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1863dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 186420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 186520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 186620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 186720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1868738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1869738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 187020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1871738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 18720024245e134467d120b40099da16c467dc365e76Andreas Huber 18730024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 187420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 187520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 187620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 187720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 187820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 187920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 188020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 18817b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 18827b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1883dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 188420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 188520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 188620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 188720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 188820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 188920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18900024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 18910024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 18920024245e134467d120b40099da16c467dc365e76Andreas Huber 189320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 189420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 189520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 189620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 189720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 189820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 189920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 190020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 190120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 190220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 19037b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 19047b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 190520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 190620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 190720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 19096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 19106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 19116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 19126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 19136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 19146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 19156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 19166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 19176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 19186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 19196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 19206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 19216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 19226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 19236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 19246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 19256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 19266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 192720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 192820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 19297b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 19307b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1931dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 193220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 193320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 193420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1935abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 1936abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 193720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1938abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1939abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 1940abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 1941abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 1942abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 1943abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1944abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1945abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 1946abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 1947abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1948abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 1949abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 1950abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 1951abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1952abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 1953abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 1954abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1955abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1956abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 195720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 1958abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 195920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 1960abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 1961abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1962abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1963abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 1964abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 1965abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 1966abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1967abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1968abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1969abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 1970abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 1971abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 1972abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 1973abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 197420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1975788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 1976788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 1977788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 1978788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 1979788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 1980788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 198120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 19825295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 19835295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 19845295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 19855295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 19865295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 19875295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 19885295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 19895295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 199020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 199120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 199220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1993abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1994abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 1995abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1996abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1997abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 1998abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 1999abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 2000abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 2001abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2002abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 2003abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 2004abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 2005abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 2006abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 2007abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 2008abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2009abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 201020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 201120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 201220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 201320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 201420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 201520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 201620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 201720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2018c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 20190024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 20204678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t cts; 20218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 2022dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 2023dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 2024dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 202520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2026c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 2027c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 20284678a6dc5f09008481524949a9667af5a6190374Andreas Huber mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 202920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2030dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 2031dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 2032dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2033dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2034dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 2035c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 2036dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 2037ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 2038dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 2039dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 20400024245e134467d120b40099da16c467dc365e76Andreas Huber } 204120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2042dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 2043dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 2044dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 204534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 2046dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2047dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 2048dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 2049dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 2050dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2051dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 2052dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2053dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 20547b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 2055dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 2056dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 205748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 20584678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2059abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2060abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 2061abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 2062abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 2063abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2064abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 20658bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 20668bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 20678bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 20688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 2069dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 2070dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2071dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2072dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 2073dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 2074dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 2075dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2076dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 2077dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2078dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2079dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 2080dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 2081dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 20826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 2083dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2084dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 2085dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 2086dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 20876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 2088e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 2089e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 2090e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2091e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 2092e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 2093e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2094e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 2095e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 2096dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2097dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 20987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 20996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 2100dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 21017b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 2102dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 21036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 21046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 2105dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2106dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 2107dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 2108dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 2109dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2110dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2111dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 2112dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2113dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 2114dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 2115dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 2116dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 2117dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 2118dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 2119dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 2120dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 2121dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 2122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 2123dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 2124dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 2125dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 212620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 212720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 212820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 212920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 213020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2131dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 213220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 213320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2134dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 2135dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 2136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 21376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 2138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 2139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 2140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 2141dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 2142e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2143dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 214434fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 214534fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 214634fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 214734fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 214834fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 214934fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 215034fe252c89e33572d01fea981b58d7b115e76164James Dong } 2151e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 215234fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 215334fe252c89e33572d01fea981b58d7b115e76164James Dong LOGE("Video is malformed"); 2154dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 2155dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 2156dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 2157dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2158dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2159dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 2160dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 2161dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2162dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2163dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 2164dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2165dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2166dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2167dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2168dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 2169dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 2170dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 2171dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 2172dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2173dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 2174dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 2175dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 2176dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2177dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 217820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 217948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 21804678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2181abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2182abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 2183abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 2184abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 2185abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2186abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 21878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 21888bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 21898bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 21908bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 219120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 219220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 219320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 219420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 219520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 219620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 219720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 219820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 219920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2200bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 2201bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 2202bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 2203bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 2204bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 2205bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 2206bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 2207bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 2208bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 2209bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 2210bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 2211bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 2212bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 2213bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 22141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 2215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 221620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 221720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 221834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 221920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 222020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 222120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 222220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 222320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2224b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2225b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 22260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2227ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2228983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 222918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 22305a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 223120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 223220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 223320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 223420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 223520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 223620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 223720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 22391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 22401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 22411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 22421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 22431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 22441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 22451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 22464cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 22474cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 22484cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 22494cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 22504cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 225158fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 225258fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 225358fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 22541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 22551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 22561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 22571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 22581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 22591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 22601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 22611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 22641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 22651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 22661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 22671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 22681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 22691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 22701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 22711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t header[12]; 22721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(0, header, 12) != 12 22731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber || memcmp("ftyp", &header[4], 4)) { 22741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 22751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 22771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t atomSize = U32_AT(&header[0]); 22781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 22791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 22801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 22821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber bool success = false; 22831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 22841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 22851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } else { 22861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 22871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 22881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t tmp[4]; 22891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 22901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 22911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 22931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 22941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 22951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 22961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22971b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 22991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23001b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (!success) { 23011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 23021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 23031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 23055a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 23061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 23081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 23091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 23115a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 23125a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 23131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 23141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 23151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 23161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 23181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 23191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 23201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 23211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 23231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 23241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 232520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 232620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2327