MPEG4Extractor.cpp revision 50a9976892316c033cd90d522ecbfcc8e3c0eb9b
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> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 33dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber#include <media/stagefright/MediaDebug.h> 3418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 63693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 65693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 790024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 800024245e134467d120b40099da16c467dc365e76Andreas Huber 816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 8850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 8950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ssize_t readAt(off_t offset, void *data, size_t size); 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t getSize(off_t *size); 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber status_t setCachedRange(off_t offset, size_t size); 10350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 10650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber off_t mCachedOffset; 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) { 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 23818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 240371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 242371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 24718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 253dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 258693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 2617be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 26472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData(new MetaData) { 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2787be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2797be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2807be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 28172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2827be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 2837be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 28472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 2857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 2867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 320371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 321371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 322371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 323371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 334c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 335c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 336c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3567be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 35872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 35972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 36072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 36172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 36272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 36372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 37972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 38072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 38172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 38272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 38472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 38572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 38672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 38872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 38972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 39072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 39272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 39372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 39472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 39672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 39772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 39872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 39972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 40072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 40172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 40272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 40372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 40472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 40572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 40672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 40772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 40872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 40972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 41172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 41272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 41534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 42334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 44072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt(*offset, buffer, chunk_size) 44172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)chunk_size) { 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 45072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 45472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 45572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 45672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 45772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 45872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 45972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 46072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 46172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 46272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 46372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(*offset, stop_offset); 46472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 46572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 46672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 46772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 48072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 48172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 48350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 48450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 48550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 48650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mDataSource->flags() & DataSource::kWantsPrefetching) { 48750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 48850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 48950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 49050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 49150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 49250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 49350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 49450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 49550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 504dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 516dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 51934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 53334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 55034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 55120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 5727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = false; 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 58834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 60534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 61534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 62334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 63148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 64434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 670dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 67134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 696dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 702371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 72318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 72418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 72518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 733134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' %d channels, size %d, rate %d\n", 734134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, num_channels, sample_size, sample_rate); 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 73820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 748dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 7567be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 7577be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 777134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 778134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 792dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 836738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 837738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 838738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 839738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 840738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 841738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 842738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 843738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 844738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 86120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 87420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 88920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 89020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 89620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 91420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 92572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 92672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 92772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 92872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 92972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 93072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 93172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 93272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 93372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 93472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 93572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 93672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 93772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 93872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 93972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 94072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 94172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 94272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 94372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 94472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 94572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 94672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(*offset, stop_offset); 94772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 94872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 94972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 95072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 95172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 95272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 95372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 95472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 95572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 95672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 95772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 95872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 95972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 96072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 96172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 96272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 96372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 96472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 96572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 96672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 96772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 96872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 96972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 97172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 97272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 97372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 97472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 97572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 97672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 97872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 97972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 98072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 98172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(header[0], 0); 98272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 98372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 98472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 98572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 98672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 98772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 98872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 98972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 99072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 99172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 99272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 99372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 99820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 100572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 100672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 100772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 100872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 100972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 101072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 101172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 101272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 101372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 101472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 101572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 101672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 101772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 101872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 101972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 102072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 102172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 102272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 102372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 102472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 102572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 102672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 102772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 102872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 102972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 103072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 103172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 103272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 103372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 103472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 103572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 103672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 103772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 103872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 103972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 104072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 104172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 104272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 104372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 104472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 104572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 104672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 104772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 104872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 104972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 105072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 105172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 105272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 105372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 105472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 105572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 105672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 105772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 105872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 105972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 106072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 106172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 106272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 106372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 106472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber printf("track: %s\n", tmp); 106572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 106672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 106772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 106872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 106972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 107072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 107172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 107272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 107372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 107472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 107572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 107672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 107772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 107872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 107972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 108072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // uint8_t 108172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 108272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(genre, "%d", (int)buffer[size - 1]); 108372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 108572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 108672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 108772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 108872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 109072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 109172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 109272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 109372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 109472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 109572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 109672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 109772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 109872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 109972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 110120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1116371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1117371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1118371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1119371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 112148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 112948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 113220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 113348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 113420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 113520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 113620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 11376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 113820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 113920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 114020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1141dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 11420024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 114320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1145dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 114620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 11486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 11506064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 11516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 11526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 11536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 11546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 11566064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 11586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 11596064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 11616064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 11626064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 116320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 116420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 116520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 116620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 116720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 116920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 117020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 1172dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 117320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 117420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1175dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1177dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1179dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 118320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1184738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1185738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1187738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 11880024245e134467d120b40099da16c467dc365e76Andreas Huber 11890024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 119220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 1197dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 120020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 120120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 120220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12040024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 12050024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 12060024245e134467d120b40099da16c467dc365e76Andreas Huber 120720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 120820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 120920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 121020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 121120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 121220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 121320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 121620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 121720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 121820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 121920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 12216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 12226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 12236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 12246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 12256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 12266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 12276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 12286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 12296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 12306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 12316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 12336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 12346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 12356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 12366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 12376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 12386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 123920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 1241dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 124220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 124420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 124520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 124620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 124720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 124820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 124920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 125020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 125120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 125320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 125420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 125520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 125620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 125720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 125820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 125920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 126020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 126220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 126320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 126420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12650024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 12660024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1267dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 1268dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1269dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1270dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 127120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1272c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1273c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 1274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleIndex, &offset, &size, &dts); 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1276dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1277dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1278dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1279dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1280dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1282dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1283dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 1284dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1285dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 12860024245e134467d120b40099da16c467dc365e76Andreas Huber } 128720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1288dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1289dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1290dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 129134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1292dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1293dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1294dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1295dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1296dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1297dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1298dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1299dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1300dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1301dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 130248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 130348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1304dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1305dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1306dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1307dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1308dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1309dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1310dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1311dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1312dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1313dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1314dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1315dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1316dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 13176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1318dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1319dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1320dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1321dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 13226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1323e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1324e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1325e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1326e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1327e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1328e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1329e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1330e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1331dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1332dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 13336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1334dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1335dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 13366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 13376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1338dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1339dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1341dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1342dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1343dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1344dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1345dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1346dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1347dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1348dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1349dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1350dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 135234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 135320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 135520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1358dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1361dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 1362dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 1363dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 13646064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1365dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 13666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(srcOffset + mNALLengthSize <= size); 13676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 13686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber srcOffset += mNALLengthSize; 1369e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1370e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (srcOffset + nalLength > size) { 1371e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1372e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1373e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1374e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1375e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1376dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1377dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 1378dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 1379dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1380dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1381dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 1382dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1383dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1384dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1385dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1386dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 1387dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1388dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 1389dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 1390dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 13916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(srcOffset, size); 1392dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1393dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 139420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 139548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 139648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 139720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 139820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 139920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 140120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 140320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 1407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 141034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 141120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 141220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 141420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 141520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 14160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 14170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypM4A ", 8)) { 141818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 141920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 142520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 142620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1429