MPEG4Extractor.cpp revision ec9dd59902c8beea4ba6a842f3a843d46150d949
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 31ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#include "include/ESDS.h" 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 34dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber#include <media/stagefright/MediaDebug.h> 3518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 66693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 716064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 800024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 810024245e134467d120b40099da16c467dc365e76Andreas Huber 826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 8950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 9050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ssize_t readAt(off_t offset, void *data, size_t size); 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t getSize(off_t *size); 10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber status_t setCachedRange(off_t offset, size_t size); 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber off_t mCachedOffset; 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) { 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 23918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 241371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 243371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 24818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 254dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 259693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 2627be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 26572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData(new MetaData) { 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2797be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2807be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2817be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 28272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2837be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 2847be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 28572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 2867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 2877be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 321371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 322371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 323371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 324371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 335c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 336c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 337c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3577be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 35972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 36072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 36172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 36272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 36372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 36472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 38072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 38172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 38272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 38372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 38572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 38672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 38772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 38972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 39072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 39172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 39372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 39472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 39572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 39772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 39872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 39972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 40072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 40172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 40272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 40372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 40472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 40572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 40672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 40772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 40872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 40972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 41072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 41272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 41372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 41634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 42434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 44172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt(*offset, buffer, chunk_size) 44272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)chunk_size) { 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 45172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 45572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 45672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 45772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 45872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 45972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 46072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 46172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 46272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 46372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 46472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(*offset, stop_offset); 46572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 46672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 46772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 46872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 48172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 48272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 48450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 48550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 48650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 48750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mDataSource->flags() & DataSource::kWantsPrefetching) { 48850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 48950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 49050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 49150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 49250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 49350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 49450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 49550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 49650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 505dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 517dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 52034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 53434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 55134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 5737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = false; 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 58934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 60634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 61634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 62434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 63248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 64534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 671dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 67234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 697dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 703371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 72418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 72518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 72618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 734134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' %d channels, size %d, rate %d\n", 735134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, num_channels, sample_size, sample_rate); 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 73820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 749dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 7577be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 7587be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 778134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 779134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 793dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 837738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 838738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 839738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 840738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 841738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 842738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 843738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 844738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 845738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 86120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 89020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 89620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 902ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 903ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 904ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 905ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 906ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 907ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 908ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 909ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 910ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 911ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 912ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 913ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 914ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 915ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 916ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 94072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 94172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 94272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 94372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 94472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 94572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 94672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 94772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 94872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 94972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 95072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 95172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 95272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 95372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 95472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 95572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 95672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 95772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 95872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 95972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 96072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 96172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 96272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(*offset, stop_offset); 96372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 96472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 96572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 96672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 96772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 96872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 96972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 97072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 97272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 97372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 97472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 97572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 97772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 97872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 97972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 98072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 98172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 98272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 98372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 98472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 98572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 98672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 98772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 98872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 98972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 99072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 99172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 99272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 99372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 99472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 99572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 99672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 99772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(header[0], 0); 99872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 99972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 100072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 100172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 100272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 100372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 100472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 100572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 100672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 100772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 100872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 100972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 102172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 102272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 102372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 102472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 102572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 102672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 102772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 102872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 102972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 103072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 103172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 103272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 103372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 103472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 103572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 103672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 103772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 103872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 103972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 104072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 104172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 104272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 104372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 104472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 104572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 104672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 104772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 104872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 104972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 105072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 105172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 105272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 105372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 105472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 105572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 105672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 105772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 105872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 105972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 106072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 106172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 106272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 106372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 106472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 106572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 106672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 106772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 106872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 106972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 107072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 107172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 107272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 107372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 107472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 107572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 107672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 107772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 107872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 107972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber printf("track: %s\n", tmp); 108172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 108272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 108372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 108472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 108572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 108672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 108772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 108872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 109072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 109172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 109272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 109372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 109472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 109572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 109672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // uint8_t 109772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 109872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(genre, "%d", (int)buffer[size - 1]); 109972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 110072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 110172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 110272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 110372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 110472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 110572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 110672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 110772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 110872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 110972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 111072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 111172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 111272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 111372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 111472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 111572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1132371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1133371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1134371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1135371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 113748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 113820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 113920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1140ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1141ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1142ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 1143ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1144ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1145ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1146ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1147ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1148ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1149ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1150ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1151ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1152ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1153ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1154ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1155ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1156ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1157ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1158ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1159ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1160ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1161ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1162ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1163ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1164ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1165ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1166ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1167ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1168ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1169ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1170ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1171ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1172ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1173ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1174ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1175ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1176ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1177ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1178ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1179ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 1180ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber static uint32_t kSamplingRate[] = { 1181ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1182ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 16000, 12000, 11025, 8000, 7350 1183ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber }; 1184ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1185ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1186ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1187ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1188ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1189ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1190ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1191ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1192ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1193ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1194ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1195ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1196ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1197ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1198ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1199ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1200ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 1201ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1202ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1203ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1204ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1205ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1206ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1207ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1208ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1209ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1210ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 1211ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1212ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1213ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1214ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1215ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1216ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1217ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1218ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1219ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 122020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 122120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 122220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 122320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 122548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 122948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 12336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1237dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 12380024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1241dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 12446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 12466064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 12476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 12486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 12496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 12506064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 12526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 12546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 12556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12566064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 12576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 12586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 126620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 1268dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 126920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1271dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 127220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1273dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 127420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1275dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 127620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1280738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1281738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1283738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 12840024245e134467d120b40099da16c467dc365e76Andreas Huber 12850024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 128620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 128820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 129120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 1293dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 129720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 129820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13000024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 13010024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 13020024245e134467d120b40099da16c467dc365e76Andreas Huber 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 131020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 131120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 131220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 131320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 131420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 131520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 13176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 13186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 13196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 13206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 13216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 13226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 13236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 13246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 13256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 13266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 13276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 13286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 13296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 13306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 13316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 13326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 13336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 13346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 133520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 133620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 1337dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 133820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 133920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 134020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 134220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 134320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 134420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 134520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 134620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 134720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13610024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 13620024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1363dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 1364dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1365dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1366dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 136720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1368c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1369c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 1370c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleIndex, &offset, &size, &dts); 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1372dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1373dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1374dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1375dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1376dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1377c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1378dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1379dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 1380dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1381dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 13820024245e134467d120b40099da16c467dc365e76Andreas Huber } 138320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1384dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1385dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1386dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 138734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1388dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1389dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1390dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1391dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1392dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1393dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1394dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1395dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1396dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1397dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 139848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 139948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1400dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1401dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1402dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1403dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1404dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1405dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1406dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1407dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1408dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1409dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1410dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1411dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1412dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 14136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1414dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1415dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1416dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1417dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 14186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1419e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1420e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1421e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1422e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1423e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1424e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1425e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1426e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1427dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1428dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 14296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1430dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1431dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 14326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 14336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1434dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1435dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1436dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1437dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1438dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1439dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1440dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1441dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1442dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1443dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1444dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1445dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1446dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 144720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 144834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 145020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 145120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 145220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1454dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 145520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1457dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 1458dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 1459dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 14606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1461dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 14626064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(srcOffset + mNALLengthSize <= size); 14636064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 14646064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber srcOffset += mNALLengthSize; 1465e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1466e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (srcOffset + nalLength > size) { 1467e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1468e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1469e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1470e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1471e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1472dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1473dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 1474dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 1475dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1476dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1477dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 1478dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1479dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1480dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1481dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1482dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 1483dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1484dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 1485dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 1486dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 14876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(srcOffset, size); 1488dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1489dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 149020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 149148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 149248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 149320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 149420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 149520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 149620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 149720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 149820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 149920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 150020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 150120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 1503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 150420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 150520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 150634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 150720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 150820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 150920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 15120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 15130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypM4A ", 8)) { 151418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 151520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 151620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 151820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 151920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 152120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 152220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 152420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1525