MPEG4Extractor.cpp revision 6624c9fd0bc5e3858a22a04c05b5059445c1c367
1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/* 2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License. 6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at 7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software 11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and 14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License. 15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */ 16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 17e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#define LOG_TAG "MPEG4Extractor" 18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/Log.h> 19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2057515f334bcc1f66f95e342bfcaa13bf9ca802adAndreas Huber#include "include/MPEG4Extractor.h" 21bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber#include "include/SampleTable.h" 22bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber 23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <arpa/inet.h> 24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <ctype.h> 26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdint.h> 27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h> 28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h> 29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/DataSource.h> 31d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#include "include/ESDS.h" 32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h> 33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber#include <media/stagefright/MediaDebug.h> 35e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h> 36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h> 37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h> 38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h> 39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h> 40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android { 42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MPEG4Source : public MediaSource { 44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic: 45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 46be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber MPEG4Source(const sp<MetaData> &format, 47be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 48fa8de752507feaca695123911915070c1ce463b2Andreas Huber int32_t timeScale, 49be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable); 50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t start(MetaData *params = NULL); 52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t stop(); 53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual sp<MetaData> getFormat(); 55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t read( 57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 59be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected: 60be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber virtual ~MPEG4Source(); 61be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber 62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate: 63ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex mLock; 64ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber sp<MetaData> mFormat; 66be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber sp<DataSource> mDataSource; 67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t mTimescale; 68be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber sp<SampleTable> mSampleTable; 69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t mCurrentSampleIndex; 70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mIsAVC; 72db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t mNALLengthSize; 73db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mStarted; 75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBufferGroup *mGroup; 77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer *mBuffer; 79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool mWantsNALFragments; 81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 828a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber uint8_t *mSrcBuffer; 838a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 84db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t parseNALSize(const uint8_t *data) const; 85db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source(const MPEG4Source &); 87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}; 89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 90affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// This custom data source wraps an existing one and satisfies requests 91affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// falling entirely within a cached range from the cache while forwarding 92affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// all remaining requests to the wrapped datasource. 93affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// This is used to cache the full sampletable metadata for a single track, 94affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 95affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 96affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 97affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstruct MPEG4DataSource : public DataSource { 98affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber MPEG4DataSource(const sp<DataSource> &source); 99affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 100affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual status_t initCheck() const; 101affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual ssize_t readAt(off_t offset, void *data, size_t size); 102affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual status_t getSize(off_t *size); 103affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual uint32_t flags(); 104affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 105affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber status_t setCachedRange(off_t offset, size_t size); 106affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 107affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberprotected: 108affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual ~MPEG4DataSource(); 109affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 110affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberprivate: 111affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber Mutex mLock; 112affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 113affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber sp<DataSource> mSource; 114affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber off_t mCachedOffset; 115affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber size_t mCachedSize; 116affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber uint8_t *mCache; 117affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 118affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber void clearCache(); 119affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 120affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber MPEG4DataSource(const MPEG4DataSource &); 121affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 122affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}; 123affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 124affa99c52957685f5a5652ab5254b92e729651c7Andreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 125affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber : mSource(source), 126affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedOffset(0), 127affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedSize(0), 128affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCache(NULL) { 129affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 130affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 131affa99c52957685f5a5652ab5254b92e729651c7Andreas HuberMPEG4DataSource::~MPEG4DataSource() { 132affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber clearCache(); 133affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 134affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 135affa99c52957685f5a5652ab5254b92e729651c7Andreas Hubervoid MPEG4DataSource::clearCache() { 136affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (mCache) { 137affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber free(mCache); 138affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCache = NULL; 139affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 140affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 141affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedOffset = 0; 142affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedSize = 0; 143affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 144affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 145affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::initCheck() const { 146affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->initCheck(); 147affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 148affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 149affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 150affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber Mutex::Autolock autoLock(mLock); 151affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 152affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (offset >= mCachedOffset 153affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber && offset + size <= mCachedOffset + mCachedSize) { 154affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 155affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return size; 156affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 157affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 158affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->readAt(offset, data, size); 159affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 160affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 161affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) { 162affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->getSize(size); 163affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 164affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 165affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberuint32_t MPEG4DataSource::flags() { 166affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->flags(); 167affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 168affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 169affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 170affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber Mutex::Autolock autoLock(mLock); 171affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 172affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber clearCache(); 173affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 174affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCache = (uint8_t *)malloc(size); 175affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 176affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (mCache == NULL) { 177affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return -ENOMEM; 178affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 179affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 180affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedOffset = offset; 181affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedSize = size; 182affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 183affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 184affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 185affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (err < (ssize_t)size) { 186affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber clearCache(); 187affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 188affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return ERROR_IO; 189affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 190affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 191affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return OK; 192affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 193affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 194affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 195affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void hexdump(const void *_data, size_t size) { 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const uint8_t *data = (const uint8_t *)_data; 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t offset = 0; 199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (offset < size) { 200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("0x%04x ", offset); 201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t n = size - offset; 203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n > 16) { 204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber n = 16; 205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < 16; ++i) { 208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (i == 8) { 209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (offset + i < size) { 213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%02x ", data[offset + i]); 214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < n; ++i) { 222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (isprint(data[offset + i])) { 223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%c", data[offset + i]); 224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("."); 226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("\n"); 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber offset += 16; 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 235e6c409632f773e41f33188272a0072be9fcb783fAndreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch (fourcc) { 237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 238e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 239e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 241e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 242e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2432a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 244e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 2452a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 247e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 250e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 253e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 2564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!"should not be here."); 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 261be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mDataSource(source), 263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata(false), 2641cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber mHasVideo(false), 265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack(NULL), 266c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mLastTrack(NULL), 267c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData(new MetaData) { 268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 270e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *next = track->next; 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete track; 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = next; 277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = mLastTrack = NULL; 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2811cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2821cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber status_t err; 2831cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber if ((err = readMetaData()) != OK) { 284c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return new MetaData; 2851cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber } 2861cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 287c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return mFileMetaData; 2881cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber} 2891cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 290be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MPEG4Extractor::countTracks() { 291e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 292e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 293be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return 0; 294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 295e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 296be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber size_t n = 0; 297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 298e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 299be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber ++n; 300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 301e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 303be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return n; 304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 306e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 307e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber size_t index, uint32_t flags) { 308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 320e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 3232a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 3242a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 3252a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 3262a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 327e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if ((flags & kIncludeExtensiveMetaData) 328e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber && !track->includes_expensive_metadata) { 329e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->includes_expensive_metadata = true; 330e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 331e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber const char *mime; 332e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 333e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (!strncasecmp("video/", mime, 6)) { 334e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber uint32_t sampleIndex; 335e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber uint32_t sampleTime; 336e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 3371faa92a1e93f311e86dca483ed7702091137de66Andreas Huber && track->sampleTable->getMetaDataForSample( 3381faa92a1e93f311e86dca483ed7702091137de66Andreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 3391faa92a1e93f311e86dca483ed7702091137de66Andreas Huber &sampleTime) == OK) { 340e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->meta->setInt64( 341e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber kKeyThumbnailTime, 342e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 343e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 344e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 345e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 346e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return track->meta; 348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHaveMetadata) { 352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t offset = 0; 356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 3591cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHaveMetadata) { 361c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mHasVideo) { 362c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 363c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 364c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 365c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 366c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[0] = x >> 24; 375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[1] = (x >> 16) & 0xff; 376e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[2] = (x >> 8) & 0xff; 377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[3] = x & 0xff; 378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[4] = '\0'; 379e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 381c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstruct PathAdder { 382c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 383c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber : mPath(path) { 384c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mPath->push(chunkType); 385c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 386c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 387c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber ~PathAdder() { 388c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mPath->pop(); 389c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 390c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 391c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberprivate: 392c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber Vector<uint32_t> *mPath; 393c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 394c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder(const PathAdder &); 395c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder &operator=(const PathAdder &); 396c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber}; 397c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 398c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 399c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return path.size() >= 5 400c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 401c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 402c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 403c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 404c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 405c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 406c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 407c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 408c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 409c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 410c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char tmp[32]; 411c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 412c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 413c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber s->setTo(tmp); 414c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 415c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t hdr[2]; 4189a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 419e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t data_offset = *offset + 8; 424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size == 1) { 4269a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_size = ntoh64(chunk_size); 430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset += 8; 431736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber 432736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber if (chunk_size < 16) { 433736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber // The smallest valid chunk is 16 bytes long in this case. 434736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber return ERROR_MALFORMED; 435736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber } 436736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber } else if (chunk_size < 8) { 437736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber // The smallest valid chunk is 8 bytes long. 438736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber return ERROR_MALFORMED; 439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char chunk[5]; 442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MakeFourCCString(chunk_type, chunk); 443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0 445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber static const char kWhitespace[] = " "; 446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 450dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber size_t n = chunk_size; 451dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber if (n > sizeof(buffer)) { 452dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber n = sizeof(buffer); 453dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber } 454dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber if (mDataSource->readAt(*offset, buffer, n) 455dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber < (ssize_t)n) { 456dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber return ERROR_IO; 457e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 458dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber 459dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber hexdump(buffer, n); 460e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif 461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 462c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 463c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 466c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 467c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 468c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber off_t stop_offset = *offset + chunk_size; 469c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset = data_offset; 470c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber while (*offset < stop_offset) { 471c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseChunk(offset, depth + 1); 472c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 473c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 474c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 475c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 4765ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 4775ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 4785ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 4795ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 480c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 481c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return OK; 482c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 483c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch(chunk_type) { 485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 486e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 487e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 488e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 489e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 490e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'b', 'l'): 491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 496c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('u', 'd', 't', 'a'): 497c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('i', 'l', 's', 't'): 498e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 499affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 500affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 501affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 502affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (mDataSource->flags() & DataSource::kWantsPrefetching) { 503affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber sp<MPEG4DataSource> cachedSource = 504affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber new MPEG4DataSource(mDataSource); 505affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 506affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 507affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mDataSource = cachedSource; 508affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 509affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 510eb9128f9b0ee660504621381fd96f82d5bf8a3fdAndreas Huber 511eb9128f9b0ee660504621381fd96f82d5bf8a3fdAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 512affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 513affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 5144d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber bool isTrack = false; 5155ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 5164d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber isTrack = true; 5174d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 5185ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber Track *track = new Track; 5195ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->next = NULL; 5205ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (mLastTrack) { 5215ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber mLastTrack->next = track; 5225ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else { 5235ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber mFirstTrack = track; 5245ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 5255ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber mLastTrack = track; 5265ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 5275ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->meta = new MetaData; 5285ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->includes_expensive_metadata = false; 5294d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber track->skipTrack = false; 5305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->timescale = 0; 5315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 5325ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 5335ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 534e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 535e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset; 536e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 537e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 540e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 5435ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 5445ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 5455ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 5465ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 5474d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber if (isTrack) { 5484d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber if (mLastTrack->skipTrack) { 5494d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber Track *cur = mFirstTrack; 5504d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 5514d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber if (cur == mLastTrack) { 5524d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber delete cur; 5534d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber mFirstTrack = mLastTrack = NULL; 5544d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } else { 5554d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber while (cur && cur->next != mLastTrack) { 5564d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber cur = cur->next; 5574d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } 5584d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber cur->next = NULL; 5594d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber delete mLastTrack; 5604d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber mLastTrack = cur; 5614d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } 5624d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 5634d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber return OK; 5644d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } 5654d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 5665ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber status_t err = verifyTrack(mLastTrack); 5675ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 5685ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (err != OK) { 5695ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return err; 5705ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 5715ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata = true; 573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 5815ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (chunk_data_size < 4) { 5825ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 5835ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 5869a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t ctime, mtime, duration; 591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t id; 592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t width, height; 593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 36 + 60) { 596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[36 + 60]; 6009a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U64_AT(&buffer[4]); 606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U64_AT(&buffer[12]); 607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[20]); 608e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U64_AT(&buffer[28]); 609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[88]); 610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[92]); 611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 24 + 60) { 613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24 + 60]; 6179a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 618e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U32_AT(&buffer[4]); 622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U32_AT(&buffer[8]); 623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[12]); 624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U32_AT(&buffer[20]); 625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[76]); 626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[80]); 627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 6409a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, &version, sizeof(version)) 642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(version)) { 643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t timescale_offset; 647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 16; 650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 8; 652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t timescale; 6579a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(timescale)) { 660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 663e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->timescale = ntohl(timescale); 664e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 665e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t duration; 666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 6679a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 669e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration)) { 670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntoh64(duration); 673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t duration32; 6759a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration32)) { 678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntohl(duration32); 681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 682fa8de752507feaca695123911915070c1ce463b2Andreas Huber mLastTrack->meta->setInt64( 683fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'd'): 690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 8) { 692e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8]; 6965ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (chunk_data_size < (off_t)sizeof(buffer)) { 6975ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 6985ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 6995ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 7009a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, 8) < 8) { 702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (entry_count > 1) { 713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // For now we only support a single type of media per track. 7144d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 7154d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber mLastTrack->skipTrack = true; 7164d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber *offset += chunk_size; 7174d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber break; 718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + 8; 722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 727e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 7285ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 7295ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 7305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 7315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 734e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 736e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 7372a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 738e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 739e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8 + 20]; 740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 741e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic AudioSampleEntry size. 742e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 743e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 744e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7459a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 746e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 747e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 748e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 749e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 750e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 751e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 752e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 753d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 754d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 755d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 756e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 757d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber FourCC2MIME(chunk_type))) { 758d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber // AMR NB audio is always mono, 8kHz 759d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber num_channels = 1; 760d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber sample_rate = 8000; 761d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 762e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber FourCC2MIME(chunk_type))) { 763d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber // AMR WB audio is always mono, 16kHz 764e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber num_channels = 1; 765d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber sample_rate = 16000; 766e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 767e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 768d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber#if 0 769d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 770d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber chunk, num_channels, sample_size, sample_rate); 771d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber#endif 772e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 773e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 774e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 775e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 776e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 777e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 778e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 779e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 780e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 781e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 783e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 784e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 7855ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 7865ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 7875ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 7885ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 789e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 790e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 793e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 794e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 7961cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber mHasVideo = true; 7971cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[78]; 799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 800e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic VideoSampleEntry size. 801e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 802e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 803e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8049a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 805e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 808e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 810e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8132ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // printf("*** coding='%s' width=%d height=%d\n", 8142ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // chunk, width, height); 815e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 819e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 820e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 821e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 822e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 823e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 827e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 8285ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 8295ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 8305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 8315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 832e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 833e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 835e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'c', 'o'): 836e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('c', 'o', '6', '4'): 837e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 838e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 839e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 840e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 841e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 842e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 843e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 844e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 845e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 846e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 847e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 848e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 849e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 850e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'c'): 851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 852e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 853e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 854e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 855e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 856e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 857e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 858e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 859e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 861e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 862e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 863e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 864e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'z'): 865e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'z', '2'): 866e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 867e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 868e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 869e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 870e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 871e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 872e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 873e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 874e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8751bceff916a72246fa208605d50615823d7f1688bAndreas Huber size_t max_size; 8761bceff916a72246fa208605d50615823d7f1688bAndreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 8771bceff916a72246fa208605d50615823d7f1688bAndreas Huber 8781bceff916a72246fa208605d50615823d7f1688bAndreas Huber // Assume that a given buffer only contains at most 10 fragments, 8791bceff916a72246fa208605d50615823d7f1688bAndreas Huber // each fragment originally prefixed with a 2 byte length will 8801bceff916a72246fa208605d50615823d7f1688bAndreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 8811bceff916a72246fa208605d50615823d7f1688bAndreas Huber // and thus will grow by 2 bytes per fragment. 8821bceff916a72246fa208605d50615823d7f1688bAndreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 8831bceff916a72246fa208605d50615823d7f1688bAndreas Huber 884e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 885e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 886e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 887e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 888e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 't', 's'): 889e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 890e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 891e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 892e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 893e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 894e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 895e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 896e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 897e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 898e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 899e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 900e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 901e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 902e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 's'): 903e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 904e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 905e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 906e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 907e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 908e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 909e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 910e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 911e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 912e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 913e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 914e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 915e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 916e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('e', 's', 'd', 's'): 917e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 918e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 919e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 920e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 921e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 922e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[256]; 923e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 924e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 925e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 926e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9279a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 928e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 929e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 930e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 931e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 932e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 933e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 934e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 935e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 936e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 937e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 938e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 939e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 940d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (mPath.size() >= 2 941d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 942d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // Information from the ESDS must be relied on for proper 943d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // setup of sample rate and channel count for MPEG4 Audio. 944d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // The generic header appears to only contain generic 945d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // information... 946d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 947d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 948d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber &buffer[4], chunk_data_size - 4); 949d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 950d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (err != OK) { 951d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return err; 952d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 953d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 954d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 955e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 956e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 957e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 958e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 959e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 960e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 961e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 962e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 963e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 964e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 965e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9669a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 967e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 968e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 969e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 970e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 971e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 972e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 973e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 974e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 975e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 976e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 977e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 978c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('m', 'e', 't', 'a'): 979c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 980c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t buffer[4]; 9815ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (chunk_data_size < (off_t)sizeof(buffer)) { 9825ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 9835ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 9845ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 985c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 986c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber data_offset, buffer, 4) < 4) { 987c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 988c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 989c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 990c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (U32_AT(buffer) != 0) { 991c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber // Should be version 0, flags 0. 992dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber 993dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // If it's not, let's assume this is one of those 994dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // apparently malformed chunks that don't have flags 995dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // and completely different semantics than what's 996dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // in the MPEG4 specs and skip it. 997dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber *offset += chunk_size; 998dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber return OK; 999c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1000c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1001c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber off_t stop_offset = *offset + chunk_size; 1002c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset = data_offset + sizeof(buffer); 1003c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber while (*offset < stop_offset) { 1004c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseChunk(offset, depth + 1); 1005c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 1006c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 1007c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1008c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 10095ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 10105ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 10115ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 10125ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 1013c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1014c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1015c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1016c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('d', 'a', 't', 'a'): 1017c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1018c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1019c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 1020c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1021c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 1022c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 1023c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1024c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1025c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1026c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset += chunk_size; 1027c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1028c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1029c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1030c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 1031c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1032c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (chunk_data_size < 12) { 1033c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 1034c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1035c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1036c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t header[12]; 1037c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 1038c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber data_offset, header, sizeof(header)) 1039c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber < (ssize_t)sizeof(header)) { 1040c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 1041c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1042c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1043c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber int64_t creationTime; 1044c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (header[0] == 1) { 1045c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber creationTime = U64_AT(&header[4]); 10465ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else if (header[0] != 0) { 10475ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 1048c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 1049c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber creationTime = U32_AT(&header[4]); 1050c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1051c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1052c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber String8 s; 1053c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber convertTimeToDate(creationTime, &s); 1054c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1055c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 1056c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1057c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset += chunk_size; 1058c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1059c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1060c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1061e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 1062e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1063e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1064e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1065e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1066e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1067e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1068e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1069e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1070e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1071c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 1072c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size < 4) { 1073c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 1074c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1075c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1076c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 1077c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 1078c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber offset, buffer, size) != (ssize_t)size) { 1079c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber delete[] buffer; 1080c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer = NULL; 1081c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1082c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 1083c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1084c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1085c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint32_t flags = U32_AT(buffer); 1086c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1087c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint32_t metadataKey = 0; 1088c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber switch (mPath[4]) { 1089c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 1090c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1091c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyAlbum; 1092c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1093c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1094c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 1095c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1096c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyArtist; 1097c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1098c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1099c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen case FOURCC('a', 'A', 'R', 'T'): 1100c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen { 1101c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen metadataKey = kKeyAlbumArtist; 1102c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen break; 1103c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen } 1104c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 1105c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1106c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyYear; 1107c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1108c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1109c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 1110c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1111c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyTitle; 1112c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1113c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1114c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 1115c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1116c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyWriter; 1117c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1118c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1119c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 1120c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1121c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyAlbumArt; 1122c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1123c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1124c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 1125c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1126c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyGenre; 1127c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1128c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1129fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 1130fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen { 1131fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen metadataKey = kKeyGenre; 1132fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen break; 1133fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1134c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 1135c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1136c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size == 16 && flags == 0) { 1137c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char tmp[16]; 1138c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber sprintf(tmp, "%d/%d", 1139c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 1140c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1141c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1142c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1143c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1144c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1145fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 1146fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen { 1147fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen if (size == 14 && flags == 0) { 1148fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen char tmp[16]; 1149fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen sprintf(tmp, "%d/%d", 1150fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 1151fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1152fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 1153fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1154fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen break; 1155fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1156fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1157c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber default: 1158c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1159c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1160c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1161c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size >= 8 && metadataKey) { 1162c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (metadataKey == kKeyAlbumArt) { 1163c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setData( 1164c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 1165c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer + 8, size - 8); 1166c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else if (metadataKey == kKeyGenre) { 1167c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (flags == 0) { 1168fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // uint8_t genre code, iTunes genre codes are 1169fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // the standard id3 codes, except they start 1170fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 1171fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // We use standard id3 numbering, so subtract 1. 1172fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen int genrecode = (int)buffer[size - 1]; 1173fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen genrecode--; 1174fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen if (genrecode < 0) { 1175fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 1176fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1177c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char genre[10]; 1178fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen sprintf(genre, "%d", genrecode); 1179c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1180c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(metadataKey, genre); 1181fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } else if (flags == 1) { 1182fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // custom genre string 1183fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen buffer[size] = '\0'; 1184fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1185fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen mFileMetaData->setCString( 1186fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen metadataKey, (const char *)buffer + 8); 1187c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1188c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 1189c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer[size] = '\0'; 1190c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1191c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString( 1192c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey, (const char *)buffer + 8); 1193c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1194c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1195c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1196c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber delete[] buffer; 1197c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer = NULL; 1198c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1199c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return OK; 1200c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 1201c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1202be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 1204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 1205be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 1206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 1209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 1210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 1211be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 1212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 1215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 1216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 12182a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 12192a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 12202a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 12212a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 1222be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return new MPEG4Source( 1223fa8de752507feaca695123911915070c1ce463b2Andreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 1224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 12265ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber// static 12275ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 12285ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber const char *mime; 12295ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 12305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 12315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber uint32_t type; 12325ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber const void *data; 12335ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber size_t size; 12345ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 12355ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 12365ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber || type != kTypeAVCC) { 12375ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 12385ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 12395ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 12405ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 12415ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 12425ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber || type != kTypeESDS) { 12435ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 12445ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 12455ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 12465ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 12475ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return OK; 12485ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber} 12495ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 1250d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1251d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber const void *esds_data, size_t esds_size) { 1252d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber ESDS esds(esds_data, esds_size); 1253d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 1254d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber uint8_t objectTypeIndication; 1255d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1256d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber return ERROR_MALFORMED; 1257d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber } 1258d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 1259d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber if (objectTypeIndication == 0xe1) { 1260d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 1261d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 1262d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber return OK; 1263d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber } 1264d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 1265d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber const uint8_t *csd; 1266d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber size_t csd_size; 1267d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (esds.getCodecSpecificInfo( 1268d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber (const void **)&csd, &csd_size) != OK) { 1269d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1270d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1271d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1272d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#if 0 1273d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber printf("ESD of size %d\n", csd_size); 1274d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber hexdump(csd, csd_size); 1275d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#endif 1276d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1277d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (csd_size < 2) { 1278d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1279d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1280d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1281d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber uint32_t objectType = csd[0] >> 3; 1282d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1283d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (objectType == 31) { 1284d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_UNSUPPORTED; 1285d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1286d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1287d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1288d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t sampleRate = 0; 1289d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t numChannels = 0; 1290d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (freqIndex == 15) { 1291d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (csd_size < 5) { 1292d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1293d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1294d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1295d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber sampleRate = (csd[1] & 0x7f) << 17 1296d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | csd[2] << 9 1297d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | csd[3] << 1 1298d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | (csd[4] >> 7); 1299d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1300d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber numChannels = (csd[4] >> 3) & 15; 1301d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } else { 1302cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber static uint32_t kSamplingRate[] = { 1303cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1304cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber 16000, 12000, 11025, 8000, 7350 1305cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber }; 1306d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1307d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (freqIndex == 13 || freqIndex == 14) { 1308d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1309d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1310d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1311d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber sampleRate = kSamplingRate[freqIndex]; 1312d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber numChannels = (csd[1] >> 3) & 15; 1313d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1314d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1315d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (numChannels == 0) { 1316d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_UNSUPPORTED; 1317d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1318d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1319d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t prevSampleRate; 1320d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1321d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1322d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (prevSampleRate != sampleRate) { 13234a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1324d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1325d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1326d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1327d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1328d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1329d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t prevChannelCount; 1330d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1331d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1332d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (prevChannelCount != numChannels) { 13334a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1334d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1335d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1336d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1337d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1338d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1339d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return OK; 1340d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber} 1341d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1342e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1343e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1344e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source( 1345e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const sp<MetaData> &format, 1346be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 1347fa8de752507feaca695123911915070c1ce463b2Andreas Huber int32_t timeScale, 1348be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable) 1349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mFormat(format), 1350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mDataSource(dataSource), 1351fa8de752507feaca695123911915070c1ce463b2Andreas Huber mTimescale(timeScale), 1352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSampleTable(sampleTable), 1353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex(0), 1354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mIsAVC(false), 1355db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mNALLengthSize(0), 1356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted(false), 1357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup(NULL), 1358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer(NULL), 13594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments(false), 13608a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer(NULL) { 1361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *mime; 1362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 13634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(success); 1364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1365e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1366db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1367db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber if (mIsAVC) { 1368db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber uint32_t type; 1369db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber const void *data; 1370db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t size; 1371db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1372db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1373db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1374db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1375db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(size >= 7); 1376db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 1377db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1378db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // The number of bytes used to encode the length of a NAL unit. 1379db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 1380db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber } 1381e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1382e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1383e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() { 1384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mStarted) { 1385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber stop(); 1386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1387e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 1390ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1391ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 13924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!mStarted); 1393e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1394e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t val; 13954f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 1396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber && val != 0) { 13974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = true; 1398e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 13994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = false; 1400e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1401e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = new MediaBufferGroup; 1403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14041bceff916a72246fa208605d50615823d7f1688bAndreas Huber int32_t max_size; 14051bceff916a72246fa208605d50615823d7f1688bAndreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1406e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14071bceff916a72246fa208605d50615823d7f1688bAndreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 14088a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 14098a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = new uint8_t[max_size]; 1410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = true; 1412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1414e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() { 1417ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1418ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 14194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 1420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 1422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14268a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber delete[] mSrcBuffer; 14278a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = NULL; 14288a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 1429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete mGroup; 1430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = NULL; 1431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = false; 1433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = 0; 1434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 1439ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1440ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 1441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return mFormat; 1442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1444db5d662254f2ed788d32e2466739adc8d655c732Andreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1445db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber switch (mNALLengthSize) { 1446db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 1: 1447db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return *data; 1448db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 2: 1449db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return U16_AT(data); 1450db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 3: 1451db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1452db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 4: 1453db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return U32_AT(data); 1454db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber } 1455db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1456db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 1457db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // a 2-bit integer. 1458db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(!"Should not be here."); 1459db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1460db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return 0; 1461db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber} 1462db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read( 1464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **out, const ReadOptions *options) { 1465ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1466ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 14674f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 1468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1469e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = NULL; 1470e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14716624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber int64_t targetSampleTimeUs = -1; 14726624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 1473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t seekTimeUs; 14746624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber ReadOptions::SeekMode mode; 14756624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 14766624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t findFlags = 0; 14776624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber switch (mode) { 14786624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 14796624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagBefore; 14806624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 14816624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_NEXT_SYNC: 14826624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagAfter; 14836624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 14846624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 14856624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_CLOSEST: 14866624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagClosest; 14876624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 14886624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber default: 14896624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber CHECK(!"Should not be here."); 14906624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 14916624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 14926624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 1493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sampleIndex; 14946624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber status_t err = mSampleTable->findSampleAtTime( 1495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber seekTimeUs * mTimescale / 1000000, 14966624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber &sampleIndex, findFlags); 14976624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 14986624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 14996624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber // We found the closest sample already, now we want the sync 15006624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber // sample preceding it (or the sample itself of course), even 15016624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber // if the subsequent sync sample is closer. 15026624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagBefore; 15036624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 15046624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15056624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t syncSampleIndex; 15066624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (err == OK) { 15076624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber err = mSampleTable->findSyncSampleNear( 15086624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber sampleIndex, &syncSampleIndex, findFlags); 15096624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 1510e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1511e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1512d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber if (err == ERROR_OUT_OF_RANGE) { 1513d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // An attempt to seek past the end of the stream would 1514d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 1515d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // this all the way to the MediaPlayer would cause abnormal 1516d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // termination. Legacy behaviour appears to be to behave as if 1517d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // we had seeked to the end of stream, ending normally. 1518d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber err = ERROR_END_OF_STREAM; 1519d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber } 1520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15236624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t sampleTime; 15246624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 15256624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber sampleIndex, NULL, NULL, &sampleTime)); 15266624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15276624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 15286624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 15296624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 15306624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15316624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber#if 0 15326624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t syncSampleTime; 15336624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 15346624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 15356624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15366624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 15376624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber "sync sample at time %lld us", 15386624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber seekTimeUs, 15396624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber sampleTime * 1000000ll / mTimescale, 15406624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber syncSampleTime * 1000000ll / mTimescale); 15416624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber#endif 15426624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15436624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber mCurrentSampleIndex = syncSampleIndex; 1544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 1545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1548e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1549e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // fall through 1550e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1551e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15528a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber off_t offset; 15538a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber size_t size; 15544f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint32_t dts; 15554f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool newBuffer = false; 15564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer == NULL) { 15574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber newBuffer = true; 1558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15591faa92a1e93f311e86dca483ed7702091137de66Andreas Huber status_t err = 15601faa92a1e93f311e86dca483ed7702091137de66Andreas Huber mSampleTable->getMetaDataForSample( 15611faa92a1e93f311e86dca483ed7702091137de66Andreas Huber mCurrentSampleIndex, &offset, &size, &dts); 1562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 15644f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 15654f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 15664f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 15674f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mGroup->acquire_buffer(&mBuffer); 15681faa92a1e93f311e86dca483ed7702091137de66Andreas Huber 15694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 15704f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(mBuffer, NULL); 15714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 15724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 15738a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber } 1574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC || mWantsNALFragments) { 15764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (newBuffer) { 15774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ssize_t num_bytes_read = 15789a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 15794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 15804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (num_bytes_read < (ssize_t)size) { 15814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 15824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 15834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 15844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 15854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 15864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1587ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 15884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, size); 15894f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->clear(); 1590fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 1591fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 15926624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15936624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (targetSampleTimeUs >= 0) { 15946624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber mBuffer->meta_data()->setInt64( 15956624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber kKeyTargetTime, targetSampleTimeUs); 15966624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 15976624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 15984f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ++mCurrentSampleIndex; 15994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 16004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC) { 16024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = mBuffer; 16034f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 16044f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 16064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 16074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16084f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Each NAL unit is split up into its constituent fragments and 16094f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // each one of them returned in its own buffer. 16104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1611db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 16124f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16134f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber const uint8_t *src = 16144f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 16154f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1616db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t nal_size = parseNALSize(src); 1617909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1618909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber LOGE("incomplete NAL unit."); 1619909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1620909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer->release(); 1621909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer = NULL; 1622909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1623909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber return ERROR_MALFORMED; 1624909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber } 16254f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16264f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber MediaBuffer *clone = mBuffer->clone(); 1627ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(clone != NULL); 1628db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 16294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1630ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 16314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range( 1632db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 1633db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 16344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer->range_length() == 0) { 16364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 16374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 16384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 16394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16404f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = clone; 16414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 16434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } else { 16444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Whole NAL units are returned but each fragment is prefixed by 16454f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // the start code (0x00 00 00 01). 16464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t num_bytes_read = 16489a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 1649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (num_bytes_read < (ssize_t)size) { 1651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 16544f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 1655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 16574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 16584f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t srcOffset = 0; 16594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t dstOffset = 0; 1660db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 16614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber while (srcOffset < size) { 1662db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(srcOffset + mNALLengthSize <= size); 1663db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1664db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber srcOffset += mNALLengthSize; 1665909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1666909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber if (srcOffset + nalLength > size) { 1667909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer->release(); 1668909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer = NULL; 1669909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1670909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber return ERROR_MALFORMED; 1671909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber } 16724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (nalLength == 0) { 16744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber continue; 16754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 16764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 16784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 16794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 16804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 16814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 16824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 1; 16834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 16844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber srcOffset += nalLength; 16854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstOffset += nalLength; 16864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 1687db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK_EQ(srcOffset, size); 16884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1689ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 16904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, dstOffset); 1691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->clear(); 1692fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 1693fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 16946624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 16956624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (targetSampleTimeUs >= 0) { 16966624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber mBuffer->meta_data()->setInt64( 16976624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber kKeyTargetTime, targetSampleTimeUs); 16986624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 16996624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 1700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++mCurrentSampleIndex; 1701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = mBuffer; 1703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1709261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberstatic bool LegacySniffMPEG4( 1710be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t header[8]; 1712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 17139a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 1714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < (ssize_t)sizeof(header)) { 1715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 1716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1717e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1719e1130662d0455231853e7d6880bb84d8547d7229James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 1720e1130662d0455231853e7d6880bb84d8547d7229James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 17216bce6d87b3fd98e68fb54328fb4dc8e40cd2c293Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 1722dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 1723eea1eefeada90ec54488e1742e81e4226fc6ace5Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 1724e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *confidence = 0.1; 1726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1727e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 1728e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1730e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 1731e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1733261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 1734261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber static const uint32_t kCompatibleBrands[] = { 1735261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('i', 's', 'o', 'm'), 1736261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('i', 's', 'o', '2'), 1737261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('a', 'v', 'c', '1'), 1738261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('3', 'g', 'p', '4'), 1739261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('m', 'p', '4', '1'), 1740261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('m', 'p', '4', '2'), 1741261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber }; 1742261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1743261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber for (size_t i = 0; 1744261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 1745261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber ++i) { 1746261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (kCompatibleBrands[i] == fourcc) { 1747261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 1748261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1749261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1750261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1751261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 1752261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber} 1753261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1754261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 1755261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber// compatible brand is present. 1756261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberstatic bool BetterSniffMPEG4( 1757261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1758261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber uint8_t header[12]; 1759261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (source->readAt(0, header, 12) != 12 1760261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber || memcmp("ftyp", &header[4], 4)) { 1761261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 1762261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1763261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1764261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber size_t atomSize = U32_AT(&header[0]); 1765261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 1766261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 1767261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1768261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1769261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber bool success = false; 1770261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 1771261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber success = true; 1772261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } else { 1773261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 1774261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 1775261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber uint8_t tmp[4]; 1776261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 1777261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 1778261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1779261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1780261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 1781261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber success = true; 1782261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber break; 1783261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1784261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1785261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1786261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1787261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (!success) { 1788261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 1789261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1790261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1791261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1792261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber *confidence = 0.3f; 1793261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1794261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 1795261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber} 1796261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1797261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberbool SniffMPEG4( 1798261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1799261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 1800261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 1801261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1802261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1803261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 1804261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 1805261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 1806261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 1807261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1808261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 1809261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber} 1810261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 1811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 1812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1813