MPEG4Extractor.cpp revision a65ccbff6e8eb301c0d325b2ec080aeda8df2024
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 31ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#include "include/ESDS.h" 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 34dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber#include <media/stagefright/MediaDebug.h> 3518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 66693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 820024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 830024245e134467d120b40099da16c467dc365e76Andreas Huber 846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ssize_t readAt(off_t offset, void *data, size_t size); 10250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t getSize(off_t *size); 10350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber status_t setCachedRange(off_t offset, size_t size); 10650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber off_t mCachedOffset; 11550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 15050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) { 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 24118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 243371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 245371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 25018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 256dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 261693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 2647be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 26772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData(new MetaData) { 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2817be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2827be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2837be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 28472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 2867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 28772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 2887be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 2897be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 323371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 324371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 325371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 326371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 337c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 338c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 339c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3597be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 36172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 36272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 36372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 36472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 36572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 36672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 38272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 38372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 38472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 38572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 38772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 38872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 38972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 39072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 39272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 39372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 39572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 39672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 39772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 39872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 39972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 40072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 40172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 40272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 40372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 40472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 40572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 40672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 40772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 40872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 40972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 41172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 41272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 41472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 41572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 41834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 42634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 43171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 43271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 43371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 43471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 43571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 43671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 43771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 43871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 450ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 451ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 452ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 453ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 454ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 455ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 456ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 458ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 459ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 46372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 46772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 46872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 46972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 47072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 47172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 47272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 47372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 47472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 47572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 476bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 477bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 478bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 479bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 48072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 48172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 48272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 48372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 49572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 49672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 49850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 49950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 50050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 50150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mDataSource->flags() & DataSource::kWantsPrefetching) { 50250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 50350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 50450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 50550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 50650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 50750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 50850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 5091edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 5101edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 51150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 51250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 5136f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 514bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 5156f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 5166f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 517bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 518bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 519bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 520bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 521bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 522bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 523bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 524bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 525bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 526bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 527bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 5286f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 529bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 530bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 531bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 532bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 542bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 543bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 544bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 545bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 5466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 5476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 5486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 5496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 5506f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 5516f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 5526f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 5536f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 5546f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 5556f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 5566f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 5576f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 5586f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 5596f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 5606f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 5616f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 5626f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 5636f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 5646f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 565bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 566bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 567bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 568bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 569bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 570bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 580bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_data_size < 4) { 581bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 582bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 58534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 59934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 61634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 63934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 65634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 66634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 67434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 68248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 695bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_data_size < (off_t)sizeof(buffer)) { 696bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 697bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 698bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 69934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 7136f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7146f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack->skipTrack = true; 7156f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber *offset += chunk_size; 7166f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber break; 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 727bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 728bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 729bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 730bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 736371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 73820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 75381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 75481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 75518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 75681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber FourCC2MIME(chunk_type))) { 75781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR NB audio is always mono, 8kHz 75881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber num_channels = 1; 75981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 8000; 76081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 76118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 76281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR WB audio is always mono, 16kHz 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 76481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 16000; 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#if 0 76881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 76981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 77081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#endif 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 784bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 785bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 786bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 787bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 7957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 7967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 812134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 813134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 827bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 828bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 829bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 830bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 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', 'z'): 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 874738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 875738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 876738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 877738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 878738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 879738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 880738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 881738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 882738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 88920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 89020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 89820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 939ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 940ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 941ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 942ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 943ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 944ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 945ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 946ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 947ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 948ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 949ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 950ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 951ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 952ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 953ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 97872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 97972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 980bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_data_size < (off_t)sizeof(buffer)) { 981bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 982bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 983bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 98472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 98572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 98672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 98772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 98872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 98972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 99072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 991ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 992ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 993ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 994ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 995ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 996ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 997ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 99872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 99972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 100072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 100172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 100272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 100372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 100472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 100572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 100672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 100772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1008bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1009bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1010bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1011bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 101272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 101372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 101472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 101572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 101672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 101772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 101872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 101972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 102072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 102172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 102272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 102372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 102472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 102572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 102672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 102772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 102872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 102972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 103072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 103172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 103272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 103372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 103472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 103572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 103672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 103772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 103872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 103972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 104072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 104172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 104272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 104372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 104472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1045bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1046bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 104772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 104872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 104972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 105072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 105172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 105272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 105372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 105472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 105572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 105672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 105772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 105872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 105972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 106820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 107172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 107272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 107372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 107472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 107572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 107672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 107772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 107872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 107972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 108072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 108272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 108372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 108572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 108672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 108772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 108872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 108972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 109072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 109172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 109272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 109372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 109472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 109572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 109672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 109772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 109866ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 109966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 110066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 110166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 110266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 110372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 110472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 110572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 110672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 110772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 110872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 110972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 111072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 111172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 111272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 111372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 111472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 111572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 111672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 111772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 111872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 111972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 112072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 112172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 112272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 112372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 112472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 112572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 112672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 112772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 112826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 112926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 113026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 113126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 113226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 113372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 113472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 113572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 113672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 113772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 113872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 113972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 114072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 114172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 114272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 114372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 114426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 114526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 114626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (size == 14 && flags == 0) { 114726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 114826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(tmp, "%d/%d", 114926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 115026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 115126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 115226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 115326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 115426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 115526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 115672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 115772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 115872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 115972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 116072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 116172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 116272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 116372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 116472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 116572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 116672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 116726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 116826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 116926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 117026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 117126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 117226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 117326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 117426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 117526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 117672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 117726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 117872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 117972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 118026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 118126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 118226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 118326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 118426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 118526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 118672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 118772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 118872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 118972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 119072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 119172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 119272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 119372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 119472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 119572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 119672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 119772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 119872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 119972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 120072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 120220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 120320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 120520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 120620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 120720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 120820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 120920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 121120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 121320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 121420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1217371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1218371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1219371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1220371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 122248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 122320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1225bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 1226bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 1227bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 1228bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1229bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1230bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 1231bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 1232bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 1233bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1234bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1235bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 1236bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1237bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1238bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1239bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1240bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1241bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 1242bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1243bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1244bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1245bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1246bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 1247bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 1248bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1249ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1250ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1251ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 125281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 125381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 125481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 125581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 125681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 125781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 125881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 125981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 126081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 126181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 126281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 126381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1264ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1265ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1266ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1267ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1268ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1269ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1270ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1271ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1272ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1273ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1274ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1275ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1276a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 1277a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 1278a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1279a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 1280a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1281a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 1282a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 1283a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1284ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1285ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1286ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1287ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1288ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1289ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1290ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1291ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1292ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1293ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1294ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1295ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1296ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1297ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1298ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1299ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1300ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1301ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1302ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1303ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1304ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1305ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1306ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1307ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1308ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 13093c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber static uint32_t kSamplingRate[] = { 13103c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 13113c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 16000, 12000, 11025, 8000, 7350 13123c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber }; 1313ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1314ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1315ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1316ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1317ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1318ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1319ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1320ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1321ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1322ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1323ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1324ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1325ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1326ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1327ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1328ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1329ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 1330ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1331ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1332ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1333ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1334ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1335ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1336ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1337ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1338ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1339ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 1340ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1341ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1342ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1343ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1344ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1345ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1346ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1347ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1348ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 134920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 135020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 135120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 135220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 135448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 135620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 135720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 135848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 135920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 136020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 136120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 13626064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 136320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 136420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 136520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1366dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 13670024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 136820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 136920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1370dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 137120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 137218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 13736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 13746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 13756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 13766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 13776064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 13786064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 13796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 13806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 13816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 13826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 13836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 13846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 13856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 13866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 13876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 138820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 138920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 139020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 139120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 139220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 139320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 139420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 139520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 139620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 13977b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 13987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1399dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 140020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1402dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 140320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1404dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 140520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1406dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 140720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 140820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 140920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 141020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1411738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1412738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 141320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1414738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 14150024245e134467d120b40099da16c467dc365e76Andreas Huber 14160024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 141720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 141820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 141920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 142120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 142220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 14247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 14257b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1426dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 142720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 142820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 142920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 143020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 143120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 143220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14330024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 14340024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 14350024245e134467d120b40099da16c467dc365e76Andreas Huber 143620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 143720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 143820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 143920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 144020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 144120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 144320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 144420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 14467b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 14477b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 144820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 144920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 145020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14516064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 14526064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 14536064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 14546064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 14556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 14566064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 14576064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 14586064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 14596064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 14606064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 14616064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 14626064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 14636064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 14646064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 14656064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 14666064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 14676064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 14686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 14696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 147020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 147120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 14727b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 14737b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1474dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 147520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 147620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 147720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 1479abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 148020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1481abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 1483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 1484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 1485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 1486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1488abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 1489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 1490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 1492abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 1493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 1494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 1496abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 1497abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1498abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1499abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 150020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 1501abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 150220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 1503abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 1504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1505abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1506abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 1507abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 1508abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 1509abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1510abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1511abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1512abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 1513abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 1514abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 1515abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 1516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 151720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 151820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 15195295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 15205295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 15215295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 15225295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 15235295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 15245295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 15255295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 15265295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 152720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 152820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 152920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1530abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 1531abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 1532abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, NULL, NULL, &sampleTime)); 1533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1534abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1535abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 1536abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1537abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1538abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 1539abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 1540abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 1541abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 1542abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1543abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 1544abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 1545abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 1546abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 1547abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 1548abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 1549abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1550abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 155120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 155220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 155320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 155420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 155520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 155620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 155720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 155820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15590024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 15600024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1561dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 15628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 1563dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1564dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1565dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 156620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1567c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1568c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 15698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample); 157020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1571dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1572dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1573dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1574dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1575dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1576c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1577dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1578dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 1579dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1580dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 15810024245e134467d120b40099da16c467dc365e76Andreas Huber } 158220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1583dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1584dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1585dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 158634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1587dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1588dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1589dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1590dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1591dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1592dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1593dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1594dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 15957b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1596dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1597dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 159848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 159948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1600abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1601abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1602abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1603abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1604abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1605abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 16068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 16078bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 16088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 16098bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 1610dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1611dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1612dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1613dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1614dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1615dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1616dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1617dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1618dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1619dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1620dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1621dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1622dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 16236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1624dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1625dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1626dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1627dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 16286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1629e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1630e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1631e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1632e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1633e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1634e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1635e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1636e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1637dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1638dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 16397b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 16406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1641dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 16427b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1643dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 16446064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 16456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1646dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1647dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1648dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1649dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1650dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1651dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1652dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1653dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1654dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1655dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1656dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1657dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1658dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 165920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 166034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 166120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 166320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 166520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1666dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 166720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1669dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 1670dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 1671dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 16726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1673dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 16746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(srcOffset + mNALLengthSize <= size); 16756064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 16766064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber srcOffset += mNALLengthSize; 1677e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1678e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (srcOffset + nalLength > size) { 1679e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1680e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1681e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1682e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1683e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1684dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1685dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 1686dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 1687dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1688dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1689dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 1690dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1691dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1692dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1693dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1694dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 1695dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1696dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 1697dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 1698dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 16996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(srcOffset, size); 1700dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 17017b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1702dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 170320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 170448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 170548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1706abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1707abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1708abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1709abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1710abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1711abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 17128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 17138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 17148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 17158bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 171620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 171720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 171820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 171920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 172020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 172220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 172320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 172420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 1726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 173220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1735b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 1736b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 17370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 1738ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 1739983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 174018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 174120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 174220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 174320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 174420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 174520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 174620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 174720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 174820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 17501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 17511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 17521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 17531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 17541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 17551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 17561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 17571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 17581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 17591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 17601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 17611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 17621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 17631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 17641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 17651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 17661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 17671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 17681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 17691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 17701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 17711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 17721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 17731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 17741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t header[12]; 17751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(0, header, 12) != 12 17761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber || memcmp("ftyp", &header[4], 4)) { 17771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 17781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 17791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 17801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t atomSize = U32_AT(&header[0]); 17811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 17821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 17831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 17841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 17851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber bool success = false; 17861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 17871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 17881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } else { 17891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 17901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 17911b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t tmp[4]; 17921b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 17931b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 17941b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 17951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 17961b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 17971b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 17981b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 17991b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 18001b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 18011b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 18021b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 18031b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (!success) { 18041b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 18051b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 18061b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 18071b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 18081b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *confidence = 0.3f; 18091b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 18101b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 18111b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 18121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 18131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 18141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 18151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 18161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 18171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 18181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 18191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 18201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 18211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 18221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 18231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 18241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 18251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 18261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 182720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 182820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1829