MPEG4Extractor.cpp revision 5d2f8ba30c24ea597d54468cda01c7ec5f6a0e66
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include "include/ESDS.h" 2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 32a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 50693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 62693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 657b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 67693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 830024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 840024245e134467d120b40099da16c467dc365e76Andreas Huber 856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 102c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 103c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong virtual status_t getSize(off64_t *size); 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 106c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong status_t setCachedRange(off64_t offset, size_t size); 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 115c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCachedOffset; 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 150c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 162c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 170c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 24218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 244371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 246371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 251e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 252e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 25318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 259dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 264693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 266bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck(NO_INIT), 2677be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 270dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 271dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 272dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 284dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 285dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf->IPMPData; 289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 290dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 291dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 292dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 29872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 3007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 30172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 3027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 3037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 338371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 339371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 340371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 351c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 352c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 353c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 365bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck != NO_INIT) { 366bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 369c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 0; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3737be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 374bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (mInitCheck == OK) { 37572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 37672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 37772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 37872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 37972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 38072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 3814678a6dc5f09008481524949a9667af5a6190374Andreas Huber mInitCheck = OK; 382bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } else { 383bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = err; 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 386bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 387bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return mInitCheck; 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 400dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 407dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 409c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongint32_t readSize(off64_t offset, 410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 412dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 414dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 415dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 416dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 417dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 418dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 419dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 420dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 421dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 422dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 423dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 429c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { 430dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 431dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 432dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 433dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 434dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 435dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 436dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 437dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 438dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 439dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 440dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 441dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 442dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 443dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 444dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 445dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t classSize = size; 446dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 447dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 448dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 449dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 450dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 451dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 452dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 453dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 454dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 455dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 456dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 457dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 458dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 459dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 460dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 461dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 462dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 463dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 464dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 465dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 466dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 467dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 468dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 469dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 470dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 471dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 472dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 473dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 474dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 475dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 476dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 477dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 478dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 479dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 480dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 481dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 482dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 483dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 484dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 485dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 486dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 487dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 488dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 489dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 490dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 491dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 492dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 493dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 494dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 495dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 496dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 497dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 498dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 499dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 500dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 501dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 502dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 503dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 504dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 505dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 506dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang classSize = size; 507dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 508dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 509dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 510dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 511dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 512dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 513dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 514dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 515dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 516dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 517dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 518dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 519dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 520dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 521dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 522dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 523dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 524dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 525dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 526dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 527dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 528dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 529dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 530dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 531dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 532dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 533dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 534dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 535dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 536dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 537dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 538dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 539dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 540dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPData = new char[sinf->len]; 541dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 542dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { 543dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 544dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 545dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 556dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 557dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 56772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 56872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 56972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 57072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 57172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 57372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 57472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 57572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 57772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 57872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 58072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 58172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 58272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 58372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 58472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 58572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 58672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 58772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 58872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 58972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 59072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 59272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 59372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 59472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 59672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 59772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 59972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 60072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 601c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 6025d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("entering parseChunk %lld/%d", *offset, depth); 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 60434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 609c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset = *offset + 8; 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 61234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 61771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 61871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 61971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 62071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 62171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 62271b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 62371b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 62471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 6295d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("chunk: %s @ %lld", chunk, *offset); 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 637ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 638ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 639ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 640ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 641ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 642ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 643ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 645ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 646ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 65072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 651c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 654515e855eae78aa495da58356486aaa666cb57fd1James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 65572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 656c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 65772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 65872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 65972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 66072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 66172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 66272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 66372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 664bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 665bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 666bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 667bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 66872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 66972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 67072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 67172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 68372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 68472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 68650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 6873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 68850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 689b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 690b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 691b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 69250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 69350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 69450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 69550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 69650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 69750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 69850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 6991edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 7001edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 70150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 70250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 7036f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 704bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 7056f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 7066f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 707bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 708bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 709bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 710bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 711bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 712bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 713bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 714bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 715bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 716bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 717bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 7186f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 719bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 720bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 721bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 722bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 723c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 732bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 733bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 734bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 735bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 7366f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 7376f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 7386f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 7396f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7406f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 7416f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 7426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 7436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 7446f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 7456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 7466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 7486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 7496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 7506f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7516f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7526f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 7536f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7546f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 756bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 757bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 758bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 759bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 760bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 761bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber mInitCheck = OK; 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 763dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 764dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 765dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 766dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 767dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 774ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 775ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 776ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 79034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 796c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t timescale_offset; 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 80734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 81734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 82534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 83348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang uint8_t lang[2]; 8367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang off64_t lang_offset; 8377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (version == 1) { 8387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 8; 8397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else if (version == 0) { 8407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_offset = timescale_offset + 4 + 4; 8417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } else { 8427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 8437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 8447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 8457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 8467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang < (ssize_t)sizeof(lang)) { 8477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang return ERROR_IO; 8487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 8497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 8507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // To get the ISO-639-2/T three character language code 8517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 8527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang // is packed as the difference between its ASCII value and 0x60. 8537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang char lang_code[4]; 8547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 8557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 8567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 8577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang lang_code[3] = '\0'; 8587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 8597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang mLastTrack->meta->setCString( 8607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang kKeyMediaLanguage, lang_code); 8617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 873c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 874bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 875bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 876bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 87734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 8903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 8913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // multiple text display formats. These formats will be used to 8923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // display the timed text. 8933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const char *mime; 8943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 8953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { 8963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For now we only support a single type of media per track. 8973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->skipTrack = true; 8983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 8993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 9003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 903c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 911bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 912bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 913bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 914bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 920371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 93781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 93881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 93918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 94081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber FourCC2MIME(chunk_type))) { 94181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR NB audio is always mono, 8kHz 94281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber num_channels = 1; 94381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 8000; 94481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 94518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 94681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR WB audio is always mono, 16kHz 94720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 94881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 16000; 94920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#if 0 95281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 95381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 95481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#endif 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 95820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 960c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 968bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 969bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 970bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 971bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 97620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 977e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('H', '2', '6', '3'): 978e071b055cee301d71335519601474c62b10af411James Dong case FOURCC('h', '2', '6', '3'): 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 9817be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 9827be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 998a6256238d9015c42129fe43791968768fe501efaJames Dong // The video sample is not stand-compliant if it has invalid dimension. 999a6256238d9015c42129fe43791968768fe501efaJames Dong // Use some default width and height value, and 1000a6256238d9015c42129fe43791968768fe501efaJames Dong // let the decoder figure out the actual width and height (and thus 1001a6256238d9015c42129fe43791968768fe501efaJames Dong // be prepared for INFO_FOMRAT_CHANGED event). 1002a6256238d9015c42129fe43791968768fe501efaJames Dong if (width == 0) width = 352; 1003a6256238d9015c42129fe43791968768fe501efaJames Dong if (height == 0) height = 288; 1004a6256238d9015c42129fe43791968768fe501efaJames Dong 1005134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 1006134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1012c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1020bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1021bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1022bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1023bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 102520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 102620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 102820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 102920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 103020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 103120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 103220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 103320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 103520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 103620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 103720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 103920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 104020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 104120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 104520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 104620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 104720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 105320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1067738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 106849110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 106949110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 107049110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 107149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 107249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1073738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 1074738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 1075738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 1076738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1077738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 1078738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 1080113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 1081113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong // Calculate average frame rate. 1082113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong const char *mime; 1083113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1084113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (!strncasecmp("video/", mime, 6)) { 1085113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1086113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int64_t durationUs; 1087113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1088113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong if (durationUs > 0) { 1089113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong int32_t frameRate = (nSamples * 1000000LL + 1090113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong (durationUs >> 1)) / durationUs; 1091113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1092113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1093113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1094113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong } 1095113a95462d2018c62b9e6bc86e7f643ff46f29cfJames Dong 109620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 109720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 109820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 110020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 110120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 110220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 110320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber case FOURCC('c', 't', 't', 's'): 11144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber { 11154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber status_t err = 11164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 11174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, chunk_data_size); 11184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 11194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (err != OK) { 11204931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return err; 11214931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 11224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 11234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber *offset += chunk_size; 11244931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber break; 11254931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 11264931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 113220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 113420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 113520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 113820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 113920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11414948818cb91176df74c972ac27b2f392b5d148bcJames Dong // @xyz 11424948818cb91176df74c972ac27b2f392b5d148bcJames Dong case FOURCC('\xA9', 'x', 'y', 'z'): 11434948818cb91176df74c972ac27b2f392b5d148bcJames Dong { 11444948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Best case the total data length inside "@xyz" box 11454948818cb91176df74c972ac27b2f392b5d148bcJames Dong // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 11464948818cb91176df74c972ac27b2f392b5d148bcJames Dong // where "\x00\x04" is the text string length with value = 4, 11474948818cb91176df74c972ac27b2f392b5d148bcJames Dong // "\0x15\xc7" is the language code = en, and "0+0" is a 11484948818cb91176df74c972ac27b2f392b5d148bcJames Dong // location (string) value with longitude = 0 and latitude = 0. 11494948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (chunk_data_size < 8) { 11504948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 11514948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 11524948818cb91176df74c972ac27b2f392b5d148bcJames Dong 11534948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Worst case the location string length would be 18, 11544948818cb91176df74c972ac27b2f392b5d148bcJames Dong // for instance +90.0000-180.0000, without the trailing "/" and 11554948818cb91176df74c972ac27b2f392b5d148bcJames Dong // the string length + language code. 11564948818cb91176df74c972ac27b2f392b5d148bcJames Dong char buffer[18]; 11574948818cb91176df74c972ac27b2f392b5d148bcJames Dong 11584948818cb91176df74c972ac27b2f392b5d148bcJames Dong // Substracting 5 from the data size is because the text string length + 11594948818cb91176df74c972ac27b2f392b5d148bcJames Dong // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 11604948818cb91176df74c972ac27b2f392b5d148bcJames Dong off64_t location_length = chunk_data_size - 5; 11614948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (location_length >= (off64_t) sizeof(buffer)) { 11624948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_MALFORMED; 11634948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 11644948818cb91176df74c972ac27b2f392b5d148bcJames Dong 11654948818cb91176df74c972ac27b2f392b5d148bcJames Dong if (mDataSource->readAt( 11664948818cb91176df74c972ac27b2f392b5d148bcJames Dong data_offset + 4, buffer, location_length) < location_length) { 11674948818cb91176df74c972ac27b2f392b5d148bcJames Dong return ERROR_IO; 11684948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 11694948818cb91176df74c972ac27b2f392b5d148bcJames Dong 11704948818cb91176df74c972ac27b2f392b5d148bcJames Dong buffer[location_length] = '\0'; 11714948818cb91176df74c972ac27b2f392b5d148bcJames Dong mFileMetaData->setCString(kKeyLocation, buffer); 11724948818cb91176df74c972ac27b2f392b5d148bcJames Dong *offset += chunk_size; 11734948818cb91176df74c972ac27b2f392b5d148bcJames Dong break; 11744948818cb91176df74c972ac27b2f392b5d148bcJames Dong } 11754948818cb91176df74c972ac27b2f392b5d148bcJames Dong 117620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 117720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 117820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 117920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 118020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 1183c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 118420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 118620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 118734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 119020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 119320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 119620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 119720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 119820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 119920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1200ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1201ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1202ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1203ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1204ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1205ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1206ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1207ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1208ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1209ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1210ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1211ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1212ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1213ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1214ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 121620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 121720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 121820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 121920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 122020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 122120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 1222c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 122320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 122634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 122920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1238244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong case FOURCC('d', '2', '6', '3'): 1239244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong { 124017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong /* 124117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * d263 contains a fixed 7 bytes part: 124217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * vendor - 4 bytes 124317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * version - 1 byte 124417e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * level - 1 byte 124517e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * profile - 1 byte 124617e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * optionally, "d263" box itself may contain a 16-byte 124717e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * bit rate box (bitr) 124817e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * average bit rate - 4 bytes 124917e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong * max bit rate - 4 bytes 125017e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong */ 125117e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong char buffer[23]; 125217e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong if (chunk_data_size != 7 && 125317e89b555a41aa591f1a01ecd51a7cb5a7bcfc0eJames Dong chunk_data_size != 23) { 125429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1255244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_MALFORMED; 1256244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1257244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1258244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong if (mDataSource->readAt( 1259244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1260244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong return ERROR_IO; 1261244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1262244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1263244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1264244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 1265244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong *offset += chunk_size; 1266244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong break; 1267244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong } 1268244ba87d20aeb29c9cad727820fa1e803ec3643cJames Dong 126972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 127072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 127172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1272c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 1273bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1274bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1275bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 127672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 127772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 127872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 127972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 128072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 128172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 128272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1283ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1284ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1285ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1286ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1287ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1288ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1289ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 129072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 129172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1292c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t stop_offset = *offset + chunk_size; 129372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 129472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 129572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 129672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 129772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 129872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 129972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1300bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1301bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1302bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1303bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 130472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 130572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 130672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 13075d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 13085d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 130972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 131072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 131172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 131272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 131372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 131472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 131572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 131672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 131772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 131872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 131972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 132072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 132172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 132272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 132372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 132472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 132572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 132672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 132772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 132872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 132972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 133072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 133172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 133272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 133372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 133472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 133572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 133772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 133872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1339bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1340bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 134172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 134272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 134372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 134472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 134572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 134672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 134772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 134872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 134972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 135072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 135172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 135272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 135372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1354dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1355dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1356dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1357dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1358dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1359dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1360dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1361dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1362dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1363dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1364dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1365dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1366dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1367dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 13683b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 13693b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang { 13703b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t buffer; 13713b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (mDataSource->readAt( 13723b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang data_offset + 8, &buffer, 4) < 4) { 13733b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 13743b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13753b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13763b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type = ntohl(buffer); 13773b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1378e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // shall be 'text'. We also want to support 'sbtl' handler type 1379e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang // for a practical reason as various MPEG4 containers use it. 1380e26dd87f87be5016777bf92e498a26d545d3926aInsun Kang if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 13813b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 13823b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13833b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13843b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang *offset += chunk_size; 13853b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang break; 13863b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13873b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang case FOURCC('t', 'x', '3', 'g'): 13897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang { 13903b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint32_t type; 13913b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang const void *data; 13923b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size_t size = 0; 13933b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (!mLastTrack->meta->findData( 13943b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 13953b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang size = 0; 13963b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 13973b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 13983b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang uint8_t *buffer = new uint8_t[size + chunk_size]; 13993b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 14003b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if (size > 0) { 14013b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang memcpy(buffer, data, size); 14023b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 14033b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 14043b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 14053b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang < chunk_size) { 14063b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 14073b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang buffer = NULL; 14083b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 14093b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang return ERROR_IO; 14103b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang } 14113b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 14123b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang mLastTrack->meta->setData( 14133b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 14143b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang 14153b573f7bf1c5736d500e39013b8d32478a1429e6Gloria Wang delete[] buffer; 14167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 14177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *offset += chunk_size; 14187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang break; 14197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang } 14207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang 1421515e855eae78aa495da58356486aaa666cb57fd1James Dong case FOURCC('c', 'o', 'v', 'r'): 1422515e855eae78aa495da58356486aaa666cb57fd1James Dong { 1423515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mFileMetaData != NULL) { 14243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("chunk_data_size = %lld and data_offset = %lld", 1425515e855eae78aa495da58356486aaa666cb57fd1James Dong chunk_data_size, data_offset); 1426515e855eae78aa495da58356486aaa666cb57fd1James Dong uint8_t *buffer = new uint8_t[chunk_data_size + 1]; 1427515e855eae78aa495da58356486aaa666cb57fd1James Dong if (mDataSource->readAt( 1428515e855eae78aa495da58356486aaa666cb57fd1James Dong data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) { 1429515e855eae78aa495da58356486aaa666cb57fd1James Dong delete[] buffer; 1430515e855eae78aa495da58356486aaa666cb57fd1James Dong buffer = NULL; 1431515e855eae78aa495da58356486aaa666cb57fd1James Dong 1432515e855eae78aa495da58356486aaa666cb57fd1James Dong return ERROR_IO; 1433515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1434515e855eae78aa495da58356486aaa666cb57fd1James Dong const int kSkipBytesOfDataBox = 16; 1435515e855eae78aa495da58356486aaa666cb57fd1James Dong mFileMetaData->setData( 1436515e855eae78aa495da58356486aaa666cb57fd1James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 1437515e855eae78aa495da58356486aaa666cb57fd1James Dong buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1438515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1439515e855eae78aa495da58356486aaa666cb57fd1James Dong 1440515e855eae78aa495da58356486aaa666cb57fd1James Dong *offset += chunk_size; 1441515e855eae78aa495da58356486aaa666cb57fd1James Dong break; 1442515e855eae78aa495da58356486aaa666cb57fd1James Dong } 1443515e855eae78aa495da58356486aaa666cb57fd1James Dong 14445d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 14455d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 14465d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 14475d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 14485d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 14495d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen *offset += chunk_size; 14505d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 14515d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 14525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 145520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 145620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 145720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 146120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1463ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1464c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, off64_t data_size) { 1465ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1466ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1467ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1468ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1469ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1470ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1471ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1472ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1473ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1474ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1475ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1476ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1477ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1478c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (data_size != (off64_t)dynSize + 60) { 1479ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1480ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1481ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1482ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1483ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1484ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1485ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1486ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1487ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 1488ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 1489ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1490ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 1491ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 1492ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 1493ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 1494ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 1495ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1496ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)version, 0u); 1497ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1498ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 1499ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 1500ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 1501ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 1502ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1503ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1504ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1505ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1506ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 1507ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1508ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1509ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1510ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1511ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1512ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1513ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1514ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1515df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("x' = %.2f * x + %.2f * y + %.2f", 1516ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1517df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("y' = %.2f * x + %.2f * y + %.2f", 1518ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1519ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1520ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1521ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 1522ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1523ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 1524ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1525ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 1526ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1527ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1528ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 1529ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1530ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 1531ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1532ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 1533ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 15345ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("We only support 0,90,180,270 degree rotation matrices"); 1535ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1536ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1537ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1538ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 1539ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1540ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1541ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1542b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // Handle presentation display size, which could be different 1543b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 1544ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 1545ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 1546b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 1547b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 1548ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1549ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 1550ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 1551ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1552c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 155372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 155472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 155572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 155672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 155772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 155872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 155972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 156072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 156172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 156272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 156372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 156472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 156572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 156672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 156772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 156872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 15695d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen char chunk[5]; 15705d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen MakeFourCCString(mPath[4], chunk); 15715d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen ALOGV("meta: %s @ %lld", chunk, offset); 157272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 157372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 157472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 157572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 157672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 157772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 157872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 157972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 158072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 158172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 158272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 158366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 158466ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 158566ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 158666ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 158766ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 158872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 158972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 159072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 159172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 159272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 159372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 159472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 159572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 159672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 159772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 159872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 159972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 160072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 160172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 160272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 160372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 160472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 160572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 160672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 160772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 160872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 160972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 161072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 161172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 161272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 161326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 161426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 161526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 161626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 161726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 161811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 161911f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen { 162011f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen if (size == 9 && flags == 21) { 162111f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen char tmp[16]; 162211f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen sprintf(tmp, "%d", 162311f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen (int)buffer[size - 1]); 162411f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen 162511f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 162611f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 162711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen break; 162811f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen } 162972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 163072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 163172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 163272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 163372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 163472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 163572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 163672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 163772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 163872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 163972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 164026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 164126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 164226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (size == 14 && flags == 0) { 164326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 164426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(tmp, "%d/%d", 164526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 164626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 164726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 164826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 164926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 165026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 16515d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('-', '-', '-', '-'): 16525d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen { 16535d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen buffer[size] = '\0'; 16545d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen switch (mPath[5]) { 16555d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('m', 'e', 'a', 'n'): 16565d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.setTo((const char *)buffer + 4); 16575d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 16585d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('n', 'a', 'm', 'e'): 16595d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.setTo((const char *)buffer + 4); 16605d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 16615d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen case FOURCC('d', 'a', 't', 'a'): 16625d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.setTo((const char *)buffer + 8); 16635d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 16645d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 16655d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen if (mLastCommentMean == "com.apple.iTunes" 16665d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen && mLastCommentName == "iTunSMPB" 16675d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen && mLastCommentData.length() != 0) { 16685d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen int32_t delay, padding; 16695d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen if (sscanf(mLastCommentData, 16705d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen " %*x %x %x %*x", &delay, &padding) == 2) { 16715d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 16725d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 16735d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 16745d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentMean.clear(); 16755d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentName.clear(); 16765d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen mLastCommentData.clear(); 16775d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 16785d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen break; 16795d2f8ba30c24ea597d54468cda01c7ec5f6a0e66Marco Nelissen } 168026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 168172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 168272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 168372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 168472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 168572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 168672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 168772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 168872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 168972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 169072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 169172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 169226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 169326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 169426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 169526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 169626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 169726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 169826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 169926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 170026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 170172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 170226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 170372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 170472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 170526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 170626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 170726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 170826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 170926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 171026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 171172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 171272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 171372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 171472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 171572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 171672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 171772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 171872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 171972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 172072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 172172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 172272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 172372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 172472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 172572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 173020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 173320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 173420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 173620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 173720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 173920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 174020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 174120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1742371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1743371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1744371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1745371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 174748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 174820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 174920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1750bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 1751bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 1752bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 1753bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1754bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 1756bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 1757bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 1758bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1759bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1760bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 1761bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1762bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1763bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1764bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1765bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1766bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 1767bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1768bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1769bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1770bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1771169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber if (!track->sampleTable->isValid()) { 1772169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber // Make sure we have all the metadata we need. 1773169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return ERROR_MALFORMED; 1774169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber } 1775169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 1776bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 1777bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 1778bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1779ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1780ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1781ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 178281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 178381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 178481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 178581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 178681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 178781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 178881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 178981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 179081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 179181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 179281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 179381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1794633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong if (objectTypeIndication == 0x6b) { 1795633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // The media subtype is MP3 audio 1796633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // Our software MP3 audio decoder may not be able to handle 1797633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 179829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("MP3 track in MP4/3GPP file is not supported"); 1799633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong return ERROR_UNSUPPORTED; 1800633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong } 1801633b4c8cc1f41370576aa43e6c5a70e4865a36dfJames Dong 1802ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1803ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1804ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1805ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1806ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1807ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1808ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1809ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1810ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1811ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1812ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1813ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1814a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 1815a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 1816a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1817a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 1818a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1819a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 1820a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 1821a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1822ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1823ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1824ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1825ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1826ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1827ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1828ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1829ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1830ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1831ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1832ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1833ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1834ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1835ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1836ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1837ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1838ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1839ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1840ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1841ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1842ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1843ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1844ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1845ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1846ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 18473c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber static uint32_t kSamplingRate[] = { 18483c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 18493c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 16000, 12000, 11025, 8000, 7350 18503c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber }; 1851ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1852ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1853ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1854ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1855ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1856ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1857ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1858ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1859ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1860ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1861ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1862ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1863ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1864ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1865ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1866ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1867ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 18683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio sample rate different from previous setting. " 1869ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1870ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1871ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1872ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1873ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1874ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1875ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1876ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1877ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 18783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("mpeg4 audio channel count different from previous setting. " 1879ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1880ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1881ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1882ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1883ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1884ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1885ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1886ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 188720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 188820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 188920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 189020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1891693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 189248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1893693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 189420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 189520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 189648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 189720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 189820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 189920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 19006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 190120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 190220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 190320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1904dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 19050024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 190620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 190720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 190920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 191018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 19116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 19126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 19136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 19146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 19156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 19166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 19176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 19186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 19196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 19206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 1921ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 19226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 19236064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 19246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 19256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 192620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 192720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 192820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 192920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 193020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 193120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 193220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 193320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 193420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 19357b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 19367b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1937dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 193820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 193920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1940dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 194120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1942dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 194320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1944dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 194520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 194620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 194720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 194820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1949738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1950738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 195120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1952738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 19530024245e134467d120b40099da16c467dc365e76Andreas Huber 19540024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 195520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 195620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 195720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 195820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 195920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 196020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 196120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 19627b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 19637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1964dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 196520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 196620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 196720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 196820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 196920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 197020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19710024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 19720024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 19730024245e134467d120b40099da16c467dc365e76Andreas Huber 197420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 197520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 197620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 197720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 197820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 197920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 198020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 198120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 198220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 198320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 19847b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 19857b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 198620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 198720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 198820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 19906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 19916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 19926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 19936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 19946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 19956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 19966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 19976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 19986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 19996064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 20006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 20016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 20026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 20036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 20046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 20056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 20066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 20076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 200820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 200920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 20107b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 20117b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 2012dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 201320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 201420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 201520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2016abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 2017abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 201820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 2019abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 2020abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 2021abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 2022abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 2023abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 2024abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 2025abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 2026abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 2027abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 2028abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 2029abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 2030abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 2031abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 2032abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 2033abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 2034abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 2035abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 2036abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2037abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 203820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 2039abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 204020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 2041abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 2042abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2043abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 2044abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 2045abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 2046abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 2047abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 2048abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2049abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2050abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 2051abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 2052abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 2053abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 2054abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 205520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2056788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber uint32_t sampleTime; 2057788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber if (err == OK) { 2058788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber err = mSampleTable->getMetaDataForSample( 2059788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber sampleIndex, NULL, NULL, &sampleTime); 2060788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber } 2061788a07fc61bad7ea2f0e3cca3f126b52a9bab376Andreas Huber 206220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 20635295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 20645295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 20655295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 20665295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 20675295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 20685295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 20695295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 20705295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 207120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 207220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 207320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2074abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 2075abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 2076abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2077abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2078abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 2079abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 2080abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 2081abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 2082abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2083df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("seek to time %lld us => sample at time %lld us, " 2084abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 2085abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 2086abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 2087abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 2088abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 2089abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2090abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 209120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 209220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 209320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 209420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 209520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 209620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 209720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 209820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2099c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset; 21000024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 21014678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t cts; 21028bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 2103dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 2104dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 2105dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 210620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2107c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 2108c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 21094678a6dc5f09008481524949a9667af5a6190374Andreas Huber mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 211020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2111dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 2112dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 2113dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2114dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2115dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 2116c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 2117dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 2118ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 2119dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 2120dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 21210024245e134467d120b40099da16c467dc365e76Andreas Huber } 212220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2123dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 2124dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 2125dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 212634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 2127dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2128dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 2129dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 2130dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 2131dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2132dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 2133dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2134dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 21357b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 2136dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 2137dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 213848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 21394678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2140abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2141abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 2142abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 2143abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 2144abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2145abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 21468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 21478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 21488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 21498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 2150dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 2151dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2152dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2153dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 2154dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 2155dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 2156dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2157dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 2158dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2159dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2160dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 2161dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 2162dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 21636064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 2164dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2165dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 2166dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 2167dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 21686064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 2169e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 217029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("incomplete NAL unit."); 2171e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2172e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 2173e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 2174e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2175e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 2176e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 2177dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2178dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 21797b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 21806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 2181dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 21827b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 2183dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 21846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 21856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 2186dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2187dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 2188dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 2189dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 2190dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2191dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2192dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 2193dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2194dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 2195dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 2196dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 2197dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 2198dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 2199dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 2200dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 2201dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 2202dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 2203dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 2204dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 2205dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 2206dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 220720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 220820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 220920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 221020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 221120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2212dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 221320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 221420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2215dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 2216dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 2217dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 22186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 2219dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 2220dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 2221dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 2222dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 2223e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 2224dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 222534fe252c89e33572d01fea981b58d7b115e76164James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 222634fe252c89e33572d01fea981b58d7b115e76164James Dong size_t nalLength = 0; 222734fe252c89e33572d01fea981b58d7b115e76164James Dong if (!isMalFormed) { 222834fe252c89e33572d01fea981b58d7b115e76164James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 222934fe252c89e33572d01fea981b58d7b115e76164James Dong srcOffset += mNALLengthSize; 223034fe252c89e33572d01fea981b58d7b115e76164James Dong isMalFormed = srcOffset + nalLength > size; 223134fe252c89e33572d01fea981b58d7b115e76164James Dong } 2232e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 223334fe252c89e33572d01fea981b58d7b115e76164James Dong if (isMalFormed) { 223429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video is malformed"); 2235dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 2236dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 2237dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 2238dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2239dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 2240dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 2241dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 2242dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2243dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2244dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 2245dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 2246dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2247dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2248dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 2249dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 2250dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 2251dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 2252dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 2253dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 2254dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 2255dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 2256dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 2257dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 2258dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 225920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 226048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 22614678a6dc5f09008481524949a9667af5a6190374Andreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2262abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 2263abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 2264abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 2265abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 2266abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 2267abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 22688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 22698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 22708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 22718bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 227220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 227320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 227420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 227520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 227620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 227720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 227820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 227920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 228020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2281bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 2282bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mimePrefix) { 2283bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 2284bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber const char *mime; 2285bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber if (track->meta != NULL 2286bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 2287bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 2288bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return track; 2289bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 2290bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber } 2291bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 2292bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber return NULL; 2293bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber} 2294bdba1f2a3813e4c8e690d71cfc2b82d5dee85c73Andreas Huber 22951b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 2296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 229720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 229820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 229934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 230020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 230120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 230220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 230320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 230420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2305b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2306b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 23070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2308ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2309983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 231018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 23115a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 231220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 231320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 231420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 231520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 231620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 231720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 231820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 23201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 23211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 23221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 23231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 23241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 23251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 23261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 23274cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong 23284cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Won't promise that the following file types can be played. 23294cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong // Just give these file types a chance. 23304cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 23314cb2c4dc7af70684e81cfbce46cbcbb9e44f4dc4James Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 233258fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber 233358fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 233458fb39120c633e3b8aa31b8f0a78e8efc193d59dAndreas Huber FOURCC('3', 'g', '2', 'b'), 23351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 23361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 23381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 23391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 23401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 23411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 23421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 23431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 23441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 23461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 23471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 23481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 23491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 2350a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// Also try to identify where this file's metadata ends 2351a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// (end of the 'moov' atom) and report it to the caller as part of 2352a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber// the metadata. 23531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 2354a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 2355a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 2356a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // We scan up to 128 bytes to identify this file as an MP4. 2357a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber static const off64_t kMaxScanOffset = 128ll; 23581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 2359a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t offset = 0ll; 2360a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool foundGoodFileType = false; 2361a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t moovAtomEndOffset = -1ll; 2362a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber bool done = false; 23631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 2364a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber while (!done && offset < kMaxScanOffset) { 2365a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t hdr[2]; 2366a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset, hdr, 8) < 8) { 2367a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 2368a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2369a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2370a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint64_t chunkSize = ntohl(hdr[0]); 2371a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t chunkType = ntohl(hdr[1]); 2372a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataOffset = offset + 8; 2373a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2374a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize == 1) { 2375a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 23761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 23771b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 23781b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 2379a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkSize = ntoh64(chunkSize); 2380a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset += 8; 2381a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2382a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkSize < 16) { 2383a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 2384a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 2385a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2386a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } else if (chunkSize < 8) { 2387a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // The smallest valid chunk is 8 bytes long. 2388a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 2389a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2390a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2391a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 2392a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2393a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber switch (chunkType) { 2394a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('f', 't', 'y', 'p'): 2395a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 2396a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (chunkDataSize < 8) { 2397a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 2398a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2399a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2400a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 2401a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 2402a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (i == 1) { 2403a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // Skip this index, it refers to the minorVersion, 2404a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber // not a brand. 2405a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber continue; 2406a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2407a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2408a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber uint32_t brand; 2409a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (source->readAt( 2410a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber chunkDataOffset + 4 * i, &brand, 4) < 4) { 2411a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 2412a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2413a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2414a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber brand = ntohl(brand); 2415a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2416a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (isCompatibleBrand(brand)) { 2417a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber foundGoodFileType = true; 2418a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 2419a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2420a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2421a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2422a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 2423a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber return false; 2424a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2425a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 24261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 24271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 2428a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2429a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber case FOURCC('m', 'o', 'o', 'v'): 2430a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber { 2431a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber moovAtomEndOffset = offset + chunkSize; 2432a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2433a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber done = true; 2434a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 2435a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2436a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2437a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber default: 2438a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber break; 24391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 2440a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2441a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber offset += chunkSize; 24421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 24431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 2444a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (!foundGoodFileType) { 24451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 24461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 24471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 24481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 24495a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 24501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 2451a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (moovAtomEndOffset >= 0) { 2452a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber *meta = new AMessage; 2453a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 2454a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 2455456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber ALOGV("found metadata size: %lld", moovAtomEndOffset); 2456a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber } 2457a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber 24581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 24591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 24601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 24611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 24625a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 2463a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber sp<AMessage> *meta) { 2464a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 24651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 24661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 24671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 24681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 24695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 24701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 24711b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 24721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 24731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 24741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 24751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 247620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 2477