MPEG4Extractor.cpp revision ba529e486dde15fe75ea1b48570f9d60a4cf3c48
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 32ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#include "include/ESDS.h" 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 3518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex mLock; 647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 66693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 820024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 830024245e134467d120b40099da16c467dc365e76Andreas Huber 846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests 9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding 9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource. 9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track, 9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource { 9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const sp<DataSource> &source); 9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t initCheck() const; 10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ssize_t readAt(off_t offset, void *data, size_t size); 10250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual status_t getSize(off_t *size); 10350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual uint32_t flags(); 10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber status_t setCachedRange(off_t offset, size_t size); 10650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected: 10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber virtual ~MPEG4DataSource(); 10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate: 11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex mLock; 11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<DataSource> mSource; 11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber off_t mCachedOffset; 11550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber size_t mCachedSize; 11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber uint8_t *mCache; 11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber void clearCache(); 11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource(const MPEG4DataSource &); 12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}; 12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber : mSource(source), 12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset(0), 12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize(0), 12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache(NULL) { 12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() { 13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() { 13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache) { 13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber free(mCache); 13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = NULL; 13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = 0; 14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = 0; 14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const { 14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->initCheck(); 14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 15050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (offset >= mCachedOffset 15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber && offset + size <= mCachedOffset + mCachedSize) { 15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return size; 15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->readAt(offset, data, size); 15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) { 16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->getSize(size); 16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() { 16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return mSource->flags(); 16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber Mutex::Autolock autoLock(mLock); 17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCache = (uint8_t *)malloc(size); 17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (mCache == NULL) { 17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return -ENOMEM; 17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedOffset = offset; 18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mCachedSize = size; 18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (err < (ssize_t)size) { 18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber clearCache(); 18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return ERROR_IO; 18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber return OK; 19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber} 19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 23818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 24118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 243371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 24418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 245371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 24718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 25018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 25318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 256dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 261693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 2647be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 26672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 267dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFileMetaData(new MetaData), 268dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF(NULL), 269dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm(false) { 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 281dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 282dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 283dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf) { 284dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *next = sinf->next; 285dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf->IPMPData; 286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang delete sinf; 287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = next; 288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = NULL; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 2947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 29572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 2967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 2977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 29872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 2997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 3007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 3187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 334371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 335371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 336371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 3387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 3397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 3407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 3457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 3467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 3477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 348c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 349c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 350c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 3517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 3527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 3537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 3547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 3577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3707be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 37272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 37372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 37472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 37572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 37672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 37772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangvoid MPEG4Extractor::setDrmFlag(bool flag) { 385dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mIsDrm = flag; 386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mFirstSINF == NULL) { 390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (trackID != sinf->trackID)) { 395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return NULL; 400dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *len = sinf->len; 403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return sinf->IPMPData; 404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 407dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangint32_t readSize(off_t offset, 408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 409dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint32_t size = 0; 410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t data; 411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool moreData = true; 412dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *numOfBytes = 0; 413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 414dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (moreData) { 415dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 416dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return -1; 417dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 418dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang offset ++; 419dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang moreData = (data >= 128) ? true : false; 420dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 421dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang (*numOfBytes) ++; 422dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 423dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return size; 425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangstatus_t MPEG4Extractor::parseDrmSINF(off_t *offset, off_t data_offset) { 428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t updateIdTag; 429dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 430dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 431dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 432dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 433dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 434dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 435dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 436dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 437dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 438dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t numOfBytes; 439dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 440dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 441dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 442dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 443dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t classSize = size; 444dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 445dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 446dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while(size >= 11 ) { 447dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t descriptorTag; 448dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 449dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 450dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 451dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 452dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 453dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 454dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 455dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 456dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 457dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t buffer[8]; 458dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 459dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 460dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 461dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 462dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 2; 463dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 464dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 465dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 466dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 467dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 468dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 469dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 470dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 471dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += 8; 472dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 473dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 474dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 475dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 476dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 477dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 478dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = new SINF; 479dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->trackID = U16_AT(&buffer[3]); 480dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPDescriptorID = buffer[7]; 481dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->next = mFirstSINF; 482dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mFirstSINF = sinf; 483dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 484dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (8 + 2 + 1); 485dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 486dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 487dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 488dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 489dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 490dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 491dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 492dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 493dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 494dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 495dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 496dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 497dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 498dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 499dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 500dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 501dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size < 0) { 502dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 503dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 504dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang classSize = size; 505dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 506dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 507dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (size > 0) { 508dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t tag; 509dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t dataLen; 510dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 511dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 512dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 513dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 514dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 515dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 516dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t id; 517dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 518dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (dataLen < 0) { 519dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 520dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else if (dataLen < 4) { 521dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 522dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 523dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += numOfBytes; 524dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 525dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 526dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 527dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 528dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset ++; 529dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 530dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang SINF *sinf = mFirstSINF; 531dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 532dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf = sinf->next; 533dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 534dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (sinf == NULL) { 535dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 536dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 537dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->len = dataLen - 3; 538dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang sinf->IPMPData = new char[sinf->len]; 539dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 540dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { 541dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_IO; 542dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 543dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang data_offset += sinf->len; 544dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 545dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size -= (dataLen + numOfBytes + 1); 546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (size != 0) { 550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} 555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 56572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 56672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 56772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 56872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 56972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 57172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 57272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 57372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 57572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 57672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 57772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 57872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 57972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 58072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 58172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 58272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 58372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 58472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 58572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 58672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 58772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 58872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 58972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 59072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 59172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 59272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 59472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 59572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 59772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 59872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 60134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 60934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 61471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber 61571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber if (chunk_size < 16) { 61671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 16 bytes long in this case. 61771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 61871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } 61971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber } else if (chunk_size < 8) { 62071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber // The smallest valid chunk is 8 bytes long. 62171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber return ERROR_MALFORMED; 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 633ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber size_t n = chunk_size; 634ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (n > sizeof(buffer)) { 635ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber n = sizeof(buffer); 636ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber } 637ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber if (mDataSource->readAt(*offset, buffer, n) 638ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber < (ssize_t)n) { 639ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return ERROR_IO; 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 641ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 642ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber hexdump(buffer, n); 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 64672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 65072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 65172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 65272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 65372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 65472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 65572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 65672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 65772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 65872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 659bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 660bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 661bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 662bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 66372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 66472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 66572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 66672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 67872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 67972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 68150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 68250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 68350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 684b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber if (mDataSource->flags() 685b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber & (DataSource::kWantsPrefetching 686b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber | DataSource::kIsCachingDataSource)) { 68750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber sp<MPEG4DataSource> cachedSource = 68850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber new MPEG4DataSource(mDataSource); 68950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 69050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 69150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber mDataSource = cachedSource; 69250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 69350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 6941edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber 6951edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 69650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber } 69750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber 6986f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber bool isTrack = false; 699bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 7006f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber isTrack = true; 7016f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 702bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber Track *track = new Track; 703bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->next = NULL; 704bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (mLastTrack) { 705bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack->next = track; 706bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else { 707bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mFirstTrack = track; 708bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 709bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber mLastTrack = track; 710bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 711bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta = new MetaData; 712bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->includes_expensive_metadata = false; 7136f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber track->skipTrack = false; 714bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->timescale = 0; 715bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 716bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 717bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 727bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 728bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 729bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 730bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 7316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (isTrack) { 7326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (mLastTrack->skipTrack) { 7336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber Track *cur = mFirstTrack; 7346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber if (cur == mLastTrack) { 7366f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete cur; 7376f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mFirstTrack = mLastTrack = NULL; 7386f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } else { 7396f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber while (cur && cur->next != mLastTrack) { 7406f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur = cur->next; 7416f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber cur->next = NULL; 7436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber delete mLastTrack; 7446f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack = cur; 7456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 7476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber return OK; 7486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber } 7496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 750bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber status_t err = verifyTrack(mLastTrack); 751bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 752bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (err != OK) { 753bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return err; 754bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 758dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 759dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return UNKNOWN_ERROR; // Return a dummy error. 760dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 761dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return OK; 762dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 769ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber status_t err; 770ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 771ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return err; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 78534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 80234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 81234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 82034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 82848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 841bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_data_size < (off_t)sizeof(buffer)) { 842bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 843bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 844bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 84534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 8596f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber 8606f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber mLastTrack->skipTrack = true; 8616f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber *offset += chunk_size; 8626f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber break; 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 873bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 874bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 875bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 876bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 882371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 89620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 89981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 90081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 90118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 90281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber FourCC2MIME(chunk_type))) { 90381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR NB audio is always mono, 8kHz 90481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber num_channels = 1; 90581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 8000; 90681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 90718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 90881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // AMR WB audio is always mono, 16kHz 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 91081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber sample_rate = 16000; 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#if 0 91481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 91581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber chunk, num_channels, sample_size, sample_rate); 91681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#endif 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 930bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 931bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 932bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 933bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 93920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 94020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 9417be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 9427be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 94320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 94420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 94520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 94620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 94720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 94820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 94934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 95220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 958134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 959134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 973bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 974bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 975bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 976bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 99820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 99920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 100020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1020738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 102149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 102249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber 102349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber if (err != OK) { 102449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber return err; 102549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber } 1026738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 1027738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 1028738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 1029738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1030738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 1031738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 1032738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 103320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 103420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 103520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 103620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 103820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 103920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 104020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 104120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 104220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 104520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 104620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 104820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 105320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 105620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 106820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 107420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 107820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 108220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 108320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 108420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 108720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 108820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1089ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (mPath.size() >= 2 1090ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1091ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // Information from the ESDS must be relied on for proper 1092ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1093ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // The generic header appears to only contain generic 1094ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber // information... 1095ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1096ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1097ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber &buffer[4], chunk_data_size - 4); 1098ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1099ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (err != OK) { 1100ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return err; 1101ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1102ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1103ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 111620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 112872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 112972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 1130bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (chunk_data_size < (off_t)sizeof(buffer)) { 1131bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1132bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1133bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 113472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 113572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 113672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 113772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 113872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 113972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 114072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 1141ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber 1142ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // If it's not, let's assume this is one of those 1143ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // apparently malformed chunks that don't have flags 1144ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // and completely different semantics than what's 1145ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber // in the MPEG4 specs and skip it. 1146ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber *offset += chunk_size; 1147ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber return OK; 114872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 114972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 115072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 115172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 115272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 115372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 115472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 115572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 115672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 115772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 1158bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1159bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (*offset != stop_offset) { 1160bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1161bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 116272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 116372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 116472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 116572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 116672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 116772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 116872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 116972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 117072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 117172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 117272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 117372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 117472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 117572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 117672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 117772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 117872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 117972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 118072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 118172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 118272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 118372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 118472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 118572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 118672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 118772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 118872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 118972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 119072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 119172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 119272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 119372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 119472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 1195bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (header[0] != 0) { 1196bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 119772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 119872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 119972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 120072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 120172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 120272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 120372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 120472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 120572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 120672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 120772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 120872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 120972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1210dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang case FOURCC('m', 'd', 'a', 't'): 1211dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang { 1212dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (!mIsDrm) { 1213dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *offset += chunk_size; 1214dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang break; 1215dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1216dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1217dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (chunk_size < 8) { 1218dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1219dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1220dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1221dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return parseDrmSINF(offset, data_offset); 1222dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1223dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 122920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1234ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1235ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber off_t data_offset, off_t data_size) { 1236ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size < 4) { 1237ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1238ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1239ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1240ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t version; 1241ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1242ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1243ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1244ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1245ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1246ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1247ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint8_t buffer[36 + 60]; 1248ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1249ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (data_size != (off_t)dynSize + 60) { 1250ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_MALFORMED; 1251ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1252ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1253ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (mDataSource->readAt( 1254ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1255ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return ERROR_IO; 1256ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1257ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1258ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint64_t ctime, mtime, duration; 1259ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t id; 1260ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1261ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (version == 1) { 1262ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U64_AT(&buffer[4]); 1263ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U64_AT(&buffer[12]); 1264ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[20]); 1265ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U64_AT(&buffer[28]); 1266ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1267ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)version, 0u); 1268ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1269ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber ctime = U32_AT(&buffer[4]); 1270ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mtime = U32_AT(&buffer[8]); 1271ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber id = U32_AT(&buffer[12]); 1272ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber duration = U32_AT(&buffer[20]); 1273ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1274ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1275ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1276ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1277ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber size_t matrixOffset = dynSize + 16; 1278ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1279ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1280ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1281ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1282ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1283ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1284ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1285ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1286ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("x' = %.2f * x + %.2f * y + %.2f", 1287ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1288ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGI("y' = %.2f * x + %.2f * y + %.2f", 1289ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1290ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1291ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1292ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t rotationDegrees; 1293ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1294ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber static const int32_t kFixedOne = 0x10000; 1295ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1296ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber // Identity, no rotation 1297ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1298ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1299ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 90; 1300ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1301ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 270; 1302ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1303ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 180; 1304ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } else { 1305ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber LOGW("We only support 0,90,180,270 degree rotation matrices"); 1306ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber rotationDegrees = 0; 1307ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1308ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1309ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (rotationDegrees != 0) { 1310ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1311ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1312ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1313ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0 1314ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 1315ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 1316ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif 1317ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 1318ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber return OK; 1319ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber} 1320ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 132172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 132272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 132372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 132472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 132572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 132672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 132772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 132872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 132972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 133072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 133172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 133372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 133472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 133672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 133772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 133872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 133972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 134072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 134172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 134272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 134372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 134472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 134572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 134672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 134772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 134872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 134966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen case FOURCC('a', 'A', 'R', 'T'): 135066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { 135166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen metadataKey = kKeyAlbumArtist; 135266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen break; 135366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen } 135472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 135572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 135672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 135772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 135872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 135972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 136072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 136172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 136272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 136372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 136472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 136572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 136672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 136772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 136872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 136972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 137072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 137172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 137272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 137372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 137472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 137572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 137672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 137772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 137872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 137926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 138026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 138126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey = kKeyGenre; 138226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 138326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 138472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 138572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 138672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 138772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 138872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 138972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 139072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 139172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 139272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 139372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 139472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 139526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 139626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen { 139726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (size == 14 && flags == 0) { 139826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen char tmp[16]; 139926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(tmp, "%d/%d", 140026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 140126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 140226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 140326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 140426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen break; 140526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 140626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 140772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 140872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 140972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 141072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 141172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 141272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 141372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 141472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 141572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 141672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 141772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 141826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // uint8_t genre code, iTunes genre codes are 141926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // the standard id3 codes, except they start 142026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 142126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // We use standard id3 numbering, so subtract 1. 142226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen int genrecode = (int)buffer[size - 1]; 142326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode--; 142426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen if (genrecode < 0) { 142526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 142626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } 142772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 142826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen sprintf(genre, "%d", genrecode); 142972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 143072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 143126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen } else if (flags == 1) { 143226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen // custom genre string 143326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen buffer[size] = '\0'; 143426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen 143526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen mFileMetaData->setCString( 143626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen metadataKey, (const char *)buffer + 8); 143772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 143872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 143972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 144072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 144172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 144272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 144372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 144572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 144672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 144772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 144872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 144972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 145072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 145172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 1452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 1455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 145620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 145720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 1461693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 146520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 146620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 146720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1468371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 1469371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 1470371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1471371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 147348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 147420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 147520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1476bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static 1477bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 1478bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const char *mime; 1479bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1480bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1481bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber uint32_t type; 1482bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber const void *data; 1483bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber size_t size; 1484bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1485bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1486bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeAVCC) { 1487bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1488bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1489bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1490bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1491bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1492bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber || type != kTypeESDS) { 1493bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return ERROR_MALFORMED; 1494bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1495bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber } 1496bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1497bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber return OK; 1498bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber} 1499bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber 1500ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1501ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const void *esds_data, size_t esds_size) { 1502ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber ESDS esds(esds_data, esds_size); 150381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 150481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber uint8_t objectTypeIndication; 150581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 150681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return ERROR_MALFORMED; 150781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 150881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 150981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (objectTypeIndication == 0xe1) { 151081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 151181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 151281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 151381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 151481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 1515ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber const uint8_t *csd; 1516ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber size_t csd_size; 1517ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (esds.getCodecSpecificInfo( 1518ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber (const void **)&csd, &csd_size) != OK) { 1519ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1520ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1521ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1522ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0 1523ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber printf("ESD of size %d\n", csd_size); 1524ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber hexdump(csd, csd_size); 1525ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif 1526ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1527a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber if (csd_size == 0) { 1528a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // There's no further information, i.e. no codec specific data 1529a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1530a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber // is accurate and hope for the best. 1531a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1532a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber return OK; 1533a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber } 1534a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber 1535ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 2) { 1536ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1537ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1538ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1539ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t objectType = csd[0] >> 3; 1540ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1541ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (objectType == 31) { 1542ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1543ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1544ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1545ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1546ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t sampleRate = 0; 1547ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t numChannels = 0; 1548ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 15) { 1549ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (csd_size < 5) { 1550ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1551ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1552ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1553ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1554ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[2] << 9 1555ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | csd[3] << 1 1556ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber | (csd[4] >> 7); 1557ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1558ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[4] >> 3) & 15; 1559ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } else { 15603c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber static uint32_t kSamplingRate[] = { 15613c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 15623c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber 16000, 12000, 11025, 8000, 7350 15633c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber }; 1564ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1565ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1566ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_MALFORMED; 1567ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1568ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1569ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1570ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber numChannels = (csd[1] >> 3) & 15; 1571ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1572ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1573ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (numChannels == 0) { 1574ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return ERROR_UNSUPPORTED; 1575ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1576ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1577ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevSampleRate; 1578ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1579ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1580ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevSampleRate != sampleRate) { 1581ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1582ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1583ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1584ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1585ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1586ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1587ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber int32_t prevChannelCount; 1588ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1589ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1590ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber if (prevChannelCount != numChannels) { 1591ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1592ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1593ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber } 1594ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1595ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1596ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 1597ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber return OK; 1598ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber} 1599ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber 160020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 160120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 160220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 160320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 160548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1606693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 160720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 160820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 160948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 161020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 161120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 161220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 16136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 161420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 161520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1617dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 16180024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1621dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 162220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 162318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 16246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 16266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 16276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 16286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 16296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 16306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 16326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 1634ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 16356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 16366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 16376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 16386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 163920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 164020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 164220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 164320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 164420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 164520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 164620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 16487b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 16497b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1650dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 165120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1653dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 165420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1655dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1657dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 165820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 165920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 166120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1662738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1663738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1665738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 16660024245e134467d120b40099da16c467dc365e76Andreas Huber 16670024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 16757b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 16767b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1677dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 167820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 168020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 168120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 168220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 168320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16840024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 16850024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 16860024245e134467d120b40099da16c467dc365e76Andreas Huber 168720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 168820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 168920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 169020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 169120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 169220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 169320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 169420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 169520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 169620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 16977b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 16987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 169920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 170020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 170120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 17036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 17046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 17056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 17066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 17076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 17086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 17096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 17106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 17116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 17126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 17136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 17156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 17166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 17176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 17186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 17196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 17206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 172220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 17237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber Mutex::Autolock autoLock(mLock); 17247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber 1725dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1729abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber int64_t targetSampleTimeUs = -1; 1730abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1732abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1733abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 1734abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t findFlags = 0; 1735abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (mode) { 1736abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 1737abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1738abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1739abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_NEXT_SYNC: 1740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagAfter; 1741abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1742abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 1743abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case ReadOptions::SEEK_CLOSEST: 1744abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagClosest; 1745abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1746abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 1747abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(!"Should not be here."); 1748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 1749abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1750abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 175120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 1752abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleTable->findSampleAtTime( 175320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 1754abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber &sampleIndex, findFlags); 1755abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1756abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1757abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // We found the closest sample already, now we want the sync 1758abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // sample preceding it (or the sample itself of course), even 1759abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // if the subsequent sync sample is closer. 1760abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber findFlags = SampleTable::kFlagBefore; 1761abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1762abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1763abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleIndex; 1764abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err == OK) { 1765abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleTable->findSyncSampleNear( 1766abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, &syncSampleIndex, findFlags); 1767abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 176820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 176920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 17705295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber if (err == ERROR_OUT_OF_RANGE) { 17715295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // An attempt to seek past the end of the stream would 17725295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 17735295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // this all the way to the MediaPlayer would cause abnormal 17745295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // termination. Legacy behaviour appears to be to behave as if 17755295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber // we had seeked to the end of stream, ending normally. 17765295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber err = ERROR_END_OF_STREAM; 17775295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber } 177820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 177920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 178020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1781abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 1782ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ((status_t)OK, mSampleTable->getMetaDataForSample( 1783abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleIndex, NULL, NULL, &sampleTime)); 1784abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1785abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 1786abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 1787abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1788abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1789abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0 1790abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t syncSampleTime; 1791abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 1792abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 1793abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1794abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 1795abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber "sync sample at time %lld us", 1796abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber seekTimeUs, 1797abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime * 1000000ll / mTimescale, 1798abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber syncSampleTime * 1000000ll / mTimescale); 1799abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif 1800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mCurrentSampleIndex = syncSampleIndex; 180220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 180320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 180420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 180820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18100024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 18110024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1812dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 18138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool isSyncSample; 1814dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1815dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 181720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1818c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1819c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 18208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample); 182120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1822dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1823dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1824dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1825dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1826dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1827c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1828dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1829ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK(mBuffer == NULL); 1830dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1831dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 18320024245e134467d120b40099da16c467dc365e76Andreas Huber } 183320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1834dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1835dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1836dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 183734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1839dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1840dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1841dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1842dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18467b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1847dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 184948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 185048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1851abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1852abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1853abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1854abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1855abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1856abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 18578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 18588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 18598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 18608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 1861dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1863dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1864dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1866dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1867dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1868dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1871dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1873dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1875dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1876dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1877dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1878dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1880e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1881e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1882e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1883e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1884e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1885e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1886e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1887e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1888dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1889dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 18907b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(clone != NULL); 18916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 18937b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber CHECK(mBuffer != NULL); 1894dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 18956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 18966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1897dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1904dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1909dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang ssize_t num_bytes_read = 0; 1910dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang int32_t drm = 0; 1911dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 1912dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 1913dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = 1914dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 1915dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1916dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 1917dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 191820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 191920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 192020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 192120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 192220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 192420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 192520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1926dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (usesDRM) { 1927dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 1928dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, size); 19296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1930dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } else { 1931dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 1932dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t srcOffset = 0; 1933dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t dstOffset = 0; 1934e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1935dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang while (srcOffset < size) { 1936dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(srcOffset + mNALLengthSize <= size); 1937dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1938dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += mNALLengthSize; 1939e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1940dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (srcOffset + nalLength > size) { 1941dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->release(); 1942dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer = NULL; 1943dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1944dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang return ERROR_MALFORMED; 1945dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1946dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang 1947dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang if (nalLength == 0) { 1948dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang continue; 1949dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1950dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1951dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 1952dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1953dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 1954dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 1955dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 0; 1956dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstData[dstOffset++] = 1; 1957dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1958dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang srcOffset += nalLength; 1959dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang dstOffset += nalLength; 1960dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang } 1961dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK_EQ(srcOffset, size); 1962dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang CHECK(mBuffer != NULL); 1963dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang mBuffer->set_range(0, dstOffset); 1964dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1965dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 196620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 196748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 196848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1969abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 1970abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (targetSampleTimeUs >= 0) { 1971abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mBuffer->meta_data()->setInt64( 1972abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber kKeyTargetTime, targetSampleTimeUs); 1973abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 1974abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 19758bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 19768bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 19778bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 19788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 197920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 198020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 198120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 198220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 198320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 198420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 198520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 198620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 198720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4( 1989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 199020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 199120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 199234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 199320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 199420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 199520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 199620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 199720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1998b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 1999b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 20000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2001ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2002983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 200318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 20045a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4; 200520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 200620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 200720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 200820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 200920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 201020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 201120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 20131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber static const uint32_t kCompatibleBrands[] = { 20141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', 'm'), 20151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('i', 's', 'o', '2'), 20161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('a', 'v', 'c', '1'), 20171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('3', 'g', 'p', '4'), 20181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '1'), 20191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber FOURCC('m', 'p', '4', '2'), 20201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber }; 20211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; 20231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 20241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber ++i) { 20251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (kCompatibleBrands[i] == fourcc) { 20261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20301b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20311b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 20321b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 20341b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present. 20351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4( 20361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 20371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t header[12]; 20381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(0, header, 12) != 12 20391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber || memcmp("ftyp", &header[4], 4)) { 20401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t atomSize = U32_AT(&header[0]); 20441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 20451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber bool success = false; 20491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 20501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 20511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } else { 20521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 20531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 20541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber uint8_t tmp[4]; 20551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 20561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 20601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber success = true; 20611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber break; 20621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (!success) { 20671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 20715a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber *confidence = 0.4f; 20721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 20751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4( 20775a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 20785a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 20791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 20801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 20841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 20851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return true; 20861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber } 20871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 20881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber return false; 20891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber} 20901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber 209120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 209220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2093