MPEG4Extractor.cpp revision ba7ec917ea91364598de1ba7a29910cec08fd5de
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; 431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char chunk[5]; 434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MakeFourCCString(chunk_type, chunk); 435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0 437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber static const char kWhitespace[] = " "; 438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size <= sizeof(buffer)) { 443c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt(*offset, buffer, chunk_size) 444c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber < (ssize_t)chunk_size) { 445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber hexdump(buffer, chunk_size); 449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif 451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 452c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 453c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 455e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 456c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 457c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 458c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber off_t stop_offset = *offset + chunk_size; 459c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset = data_offset; 460c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber while (*offset < stop_offset) { 461c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseChunk(offset, depth + 1); 462c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 463c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 464c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 465c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 466c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber CHECK_EQ(*offset, stop_offset); 467c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 468c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return OK; 469c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 470c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch(chunk_type) { 472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 477e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'b', 'l'): 478e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 479e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 482e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 483c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('u', 'd', 't', 'a'): 484c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('i', 'l', 's', 't'): 485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 486affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 487affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 488affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 489affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (mDataSource->flags() & DataSource::kWantsPrefetching) { 490affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber sp<MPEG4DataSource> cachedSource = 491affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber new MPEG4DataSource(mDataSource); 492affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 493affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 494affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mDataSource = cachedSource; 495affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 496affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 497affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 498affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 500e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset; 501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 502e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 503e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 505e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 506e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 5074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 508e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 509e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 510e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata = true; 511e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 512e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 513e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 514e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 515e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 516e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 517e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 518e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 5194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(chunk_data_size >= 4); 520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 5229a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 523e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 524e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 526e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t ctime, mtime, duration; 527e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t id; 528e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t width, height; 529e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 530e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 531e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 36 + 60) { 532e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 533e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 534e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 535e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[36 + 60]; 5369a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 537e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 540e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U64_AT(&buffer[4]); 542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U64_AT(&buffer[12]); 543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[20]); 544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U64_AT(&buffer[28]); 545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[88]); 546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[92]); 547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 548e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 24 + 60) { 549e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 550e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 551e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 552e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24 + 60]; 5539a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U32_AT(&buffer[4]); 558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U32_AT(&buffer[8]); 559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[12]); 560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U32_AT(&buffer[20]); 561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[76]); 562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[80]); 563e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = new Track; 566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->next = NULL; 567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mLastTrack) { 568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->next = track; 569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = track; 571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack = track; 573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta = new MetaData; 575e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->includes_expensive_metadata = false; 576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->timescale = 0; 577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->sampleTable = new SampleTable(mDataSource); 578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 5919a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, &version, sizeof(version)) 593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(version)) { 594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t timescale_offset; 598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 16; 601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 8; 603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t timescale; 6089a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(timescale)) { 611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->timescale = ntohl(timescale); 615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t duration; 617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 6189a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration)) { 621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntoh64(duration); 624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t duration32; 6269a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration32)) { 629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntohl(duration32); 632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 633fa8de752507feaca695123911915070c1ce463b2Andreas Huber mLastTrack->meta->setInt64( 634fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 25) { 643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24]; 6479a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(&buffer[4]) != 0) { 657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // pre_defined should be 0. 658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHandlerType = U32_AT(&buffer[8]); 662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 663e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 664e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 665e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'd'): 667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 8) { 669e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8]; 6734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 6749a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, 8) < 8) { 676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (entry_count > 1) { 687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // For now we only support a single type of media per track. 688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_UNSUPPORTED; 689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 692e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + 8; 693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 6994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 7052a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8 + 20]; 712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic AudioSampleEntry size. 714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7179a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 725e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 726e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber FourCC2MIME(chunk_type)) 727e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 728e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber FourCC2MIME(chunk_type))) { 729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // AMR audio is always mono. 730e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber num_channels = 1; 731e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 734e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7362ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // printf("*** coding='%s' %d channels, size %d, rate %d\n", 7372ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // chunk, num_channels, sample_size, sample_rate); 738e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 739e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 741e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 742e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 743e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 744e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 745e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 746e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 747e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 748e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 749e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 750e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 7514f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 752e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 753e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 754e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 755e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 756e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 757e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 758e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 7591cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber mHasVideo = true; 7601cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 761e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 762e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 763e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 764e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 765e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[78]; 766e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 767e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic VideoSampleEntry size. 768e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 769e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 770e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7719a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 772e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 773e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 774e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 775e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 776e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 777e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 778e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 779e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7802ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // printf("*** coding='%s' width=%d height=%d\n", 7812ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // chunk, width, height); 782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 783e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 784e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 785e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 786e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 788e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 789e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 790e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 793e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 794e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 7954f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 796e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 797e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'c', 'o'): 800e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('c', 'o', '6', '4'): 801e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 802e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 803e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 804e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 805e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 808e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 810e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 813e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 814e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'c'): 815e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 819e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 820e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 821e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 822e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 823e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 827e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 828e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'z'): 829e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'z', '2'): 830e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 831e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 832e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 833e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 835e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 836e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 837e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 838e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8391bceff916a72246fa208605d50615823d7f1688bAndreas Huber size_t max_size; 8401bceff916a72246fa208605d50615823d7f1688bAndreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 8411bceff916a72246fa208605d50615823d7f1688bAndreas Huber 8421bceff916a72246fa208605d50615823d7f1688bAndreas Huber // Assume that a given buffer only contains at most 10 fragments, 8431bceff916a72246fa208605d50615823d7f1688bAndreas Huber // each fragment originally prefixed with a 2 byte length will 8441bceff916a72246fa208605d50615823d7f1688bAndreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 8451bceff916a72246fa208605d50615823d7f1688bAndreas Huber // and thus will grow by 2 bytes per fragment. 8461bceff916a72246fa208605d50615823d7f1688bAndreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 8471bceff916a72246fa208605d50615823d7f1688bAndreas Huber 848e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 849e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 850e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 852e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 't', 's'): 853e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 854e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 855e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 856e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 857e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 858e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 859e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 861e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 862e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 863e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 864e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 865e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 866e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 's'): 867e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 868e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 869e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 870e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 871e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 872e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 873e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 874e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 875e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 876e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 877e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 878e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 879e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 880e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('e', 's', 'd', 's'): 881e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 882e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 883e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 884e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 885e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 886e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[256]; 887e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 888e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 889e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 890e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8919a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 892e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 893e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 894e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 895e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 896e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 897e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 898e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 899e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 900e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 901e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 902e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 903e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 904d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (mPath.size() >= 2 905d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 906d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // Information from the ESDS must be relied on for proper 907d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // setup of sample rate and channel count for MPEG4 Audio. 908d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // The generic header appears to only contain generic 909d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // information... 910d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 911d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 912d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber &buffer[4], chunk_data_size - 4); 913d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 914d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (err != OK) { 915d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return err; 916d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 917d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 918d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 919e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 920e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 921e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 922e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 923e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 924e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 925e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 926e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 927e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 928e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 929e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9309a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 931e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 932e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 933e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 934e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 935e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 936e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 937e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 938e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 939e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 940e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 941e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 942c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('m', 'e', 't', 'a'): 943c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 944c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t buffer[4]; 945c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 946c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 947c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber data_offset, buffer, 4) < 4) { 948c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 949c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 950c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 951c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (U32_AT(buffer) != 0) { 952c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber // Should be version 0, flags 0. 953c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 954c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 955c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 956c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber off_t stop_offset = *offset + chunk_size; 957c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset = data_offset + sizeof(buffer); 958c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber while (*offset < stop_offset) { 959c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseChunk(offset, depth + 1); 960c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 961c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 962c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 963c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 964c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber CHECK_EQ(*offset, stop_offset); 965c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 966c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 967c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 968c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('d', 'a', 't', 'a'): 969c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 970c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 971c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 972c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 973c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 974c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 975c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 976c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 977c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 978c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset += chunk_size; 979c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 980c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 981c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 982c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 983c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 984c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (chunk_data_size < 12) { 985c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 986c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 987c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 988c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t header[12]; 989c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 990c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber data_offset, header, sizeof(header)) 991c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber < (ssize_t)sizeof(header)) { 992c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 993c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 994c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 995c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber int64_t creationTime; 996c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (header[0] == 1) { 997c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber creationTime = U64_AT(&header[4]); 998c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 999c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber CHECK_EQ(header[0], 0); 1000c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber creationTime = U32_AT(&header[4]); 1001c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1002c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1003c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber String8 s; 1004c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber convertTimeToDate(creationTime, &s); 1005c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1006c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 1007c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1008c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset += chunk_size; 1009c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1010c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1011c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1012e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 1013e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1014e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1015e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1016e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1017e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1018e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1019e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1020e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1021e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1022c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 1023c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size < 4) { 1024c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 1025c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1026c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1027c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 1028c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 1029c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber offset, buffer, size) != (ssize_t)size) { 1030c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber delete[] buffer; 1031c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer = NULL; 1032c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1033c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 1034c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1035c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1036c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint32_t flags = U32_AT(buffer); 1037c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1038c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint32_t metadataKey = 0; 1039c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber switch (mPath[4]) { 1040c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 1041c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1042c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyAlbum; 1043c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1044c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1045c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 1046c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1047c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyArtist; 1048c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1049c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1050c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen case FOURCC('a', 'A', 'R', 'T'): 1051c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen { 1052c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen metadataKey = kKeyAlbumArtist; 1053c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen break; 1054c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen } 1055c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 1056c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1057c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyYear; 1058c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1059c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1060c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 1061c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1062c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyTitle; 1063c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1064c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1065c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 1066c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1067c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyWriter; 1068c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1069c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1070c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 1071c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1072c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyAlbumArt; 1073c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1074c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1075c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 1076c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1077c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyGenre; 1078c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1079c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1080fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 1081fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen { 1082fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen metadataKey = kKeyGenre; 1083fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen break; 1084fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1085c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 1086c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1087c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size == 16 && flags == 0) { 1088c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char tmp[16]; 1089c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber sprintf(tmp, "%d/%d", 1090c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 1091c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1092c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1093c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1094c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1095c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1096fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 1097fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen { 1098fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen if (size == 14 && flags == 0) { 1099fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen char tmp[16]; 1100fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen sprintf(tmp, "%d/%d", 1101fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 1102fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1103fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 1104fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1105fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen break; 1106fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1107fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1108c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber default: 1109c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1110c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1111c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1112c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size >= 8 && metadataKey) { 1113c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (metadataKey == kKeyAlbumArt) { 1114c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setData( 1115c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 1116c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer + 8, size - 8); 1117c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else if (metadataKey == kKeyGenre) { 1118c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (flags == 0) { 1119fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // uint8_t genre code, iTunes genre codes are 1120fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // the standard id3 codes, except they start 1121fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 1122fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // We use standard id3 numbering, so subtract 1. 1123fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen int genrecode = (int)buffer[size - 1]; 1124fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen genrecode--; 1125fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen if (genrecode < 0) { 1126fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 1127fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1128c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char genre[10]; 1129fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen sprintf(genre, "%d", genrecode); 1130c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1131c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(metadataKey, genre); 1132fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } else if (flags == 1) { 1133fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // custom genre string 1134fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen buffer[size] = '\0'; 1135fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1136fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen mFileMetaData->setCString( 1137fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen metadataKey, (const char *)buffer + 8); 1138c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1139c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 1140c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer[size] = '\0'; 1141c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1142c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString( 1143c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey, (const char *)buffer + 8); 1144c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1145c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1146c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1147c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber delete[] buffer; 1148c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer = NULL; 1149c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1150c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return OK; 1151c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 1152c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1153be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 1155e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 1156be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 1157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 1160e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 1161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 1162be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 1163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 1166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 1167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 11692a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 11702a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 11712a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 11722a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 1173be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return new MPEG4Source( 1174fa8de752507feaca695123911915070c1ce463b2Andreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 1175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1177d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1178d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber const void *esds_data, size_t esds_size) { 1179d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber ESDS esds(esds_data, esds_size); 1180d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber const uint8_t *csd; 1181d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber size_t csd_size; 1182d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (esds.getCodecSpecificInfo( 1183d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber (const void **)&csd, &csd_size) != OK) { 1184d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1185d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1186d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1187d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#if 0 1188d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber printf("ESD of size %d\n", csd_size); 1189d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber hexdump(csd, csd_size); 1190d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#endif 1191d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1192d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (csd_size < 2) { 1193d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1194d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1195d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1196d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber uint32_t objectType = csd[0] >> 3; 1197d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1198d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (objectType == 31) { 1199d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_UNSUPPORTED; 1200d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1201d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1202d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1203d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t sampleRate = 0; 1204d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t numChannels = 0; 1205d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (freqIndex == 15) { 1206d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (csd_size < 5) { 1207d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1208d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1209d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1210d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber sampleRate = (csd[1] & 0x7f) << 17 1211d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | csd[2] << 9 1212d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | csd[3] << 1 1213d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | (csd[4] >> 7); 1214d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1215d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber numChannels = (csd[4] >> 3) & 15; 1216d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } else { 1217d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber static uint32_t kSamplingRate[] = { 1218d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1219d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 16000, 12000, 11025, 8000, 7350 1220d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber }; 1221d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1222d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (freqIndex == 13 || freqIndex == 14) { 1223d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1224d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1225d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1226d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber sampleRate = kSamplingRate[freqIndex]; 1227d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber numChannels = (csd[1] >> 3) & 15; 1228d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1229d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1230d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (numChannels == 0) { 1231d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_UNSUPPORTED; 1232d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1233d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1234d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t prevSampleRate; 1235d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1236d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1237d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (prevSampleRate != sampleRate) { 12384a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1239d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1240d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1241d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1242d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1243d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1244d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t prevChannelCount; 1245d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1246d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1247d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (prevChannelCount != numChannels) { 12484a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1249d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1250d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1251d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1252d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1253d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1254d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return OK; 1255d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber} 1256d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1259e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source( 1260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const sp<MetaData> &format, 1261be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 1262fa8de752507feaca695123911915070c1ce463b2Andreas Huber int32_t timeScale, 1263be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable) 1264e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mFormat(format), 1265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mDataSource(dataSource), 1266fa8de752507feaca695123911915070c1ce463b2Andreas Huber mTimescale(timeScale), 1267e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSampleTable(sampleTable), 1268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex(0), 1269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mIsAVC(false), 1270db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mNALLengthSize(0), 1271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted(false), 1272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup(NULL), 1273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer(NULL), 12744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments(false), 12758a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer(NULL) { 1276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *mime; 1277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 12784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(success); 1279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1280e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1281db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1282db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber if (mIsAVC) { 1283db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber uint32_t type; 1284db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber const void *data; 1285db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t size; 1286db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1287db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1288db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1289db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1290db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(size >= 7); 1291db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 1292db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1293db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // The number of bytes used to encode the length of a NAL unit. 1294db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 1295db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber } 1296e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1298e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() { 1299e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mStarted) { 1300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber stop(); 1301e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 1305ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1306ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 13074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!mStarted); 1308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t val; 13104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 1311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber && val != 0) { 13124f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = true; 1313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 13144f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = false; 1315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = new MediaBufferGroup; 1318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 13191bceff916a72246fa208605d50615823d7f1688bAndreas Huber int32_t max_size; 13201bceff916a72246fa208605d50615823d7f1688bAndreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 13221bceff916a72246fa208605d50615823d7f1688bAndreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 13238a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 13248a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = new uint8_t[max_size]; 1325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = true; 1327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1329e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1330e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() { 1332ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1333ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 13344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 1335e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1336e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 1337e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1338e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1339e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1340e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 13418a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber delete[] mSrcBuffer; 13428a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = NULL; 13438a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 1344e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete mGroup; 1345e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = NULL; 1346e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = false; 1348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = 0; 1349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 1354ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1355ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 1356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return mFormat; 1357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1359db5d662254f2ed788d32e2466739adc8d655c732Andreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1360db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber switch (mNALLengthSize) { 1361db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 1: 1362db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return *data; 1363db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 2: 1364db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return U16_AT(data); 1365db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 3: 1366db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1367db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 4: 1368db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return U32_AT(data); 1369db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber } 1370db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1371db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 1372db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // a 2-bit integer. 1373db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(!"Should not be here."); 1374db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1375db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return 0; 1376db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber} 1377db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read( 1379e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **out, const ReadOptions *options) { 1380ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1381ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 13824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 1383e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = NULL; 1385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t seekTimeUs; 1387e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 1388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sampleIndex; 1389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = mSampleTable->findClosestSample( 1390e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber seekTimeUs * mTimescale / 1000000, 1391e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 1392e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1393e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1394e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1395e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = sampleIndex; 1398e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 1399e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1400e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1401e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // fall through 1404e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1405e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14068a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber off_t offset; 14078a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber size_t size; 14084f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint32_t dts; 14094f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool newBuffer = false; 14104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer == NULL) { 14114f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber newBuffer = true; 1412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14131faa92a1e93f311e86dca483ed7702091137de66Andreas Huber status_t err = 14141faa92a1e93f311e86dca483ed7702091137de66Andreas Huber mSampleTable->getMetaDataForSample( 14151faa92a1e93f311e86dca483ed7702091137de66Andreas Huber mCurrentSampleIndex, &offset, &size, &dts); 1416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14174f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 14184f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 14194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 14204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14214f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mGroup->acquire_buffer(&mBuffer); 14221faa92a1e93f311e86dca483ed7702091137de66Andreas Huber 14234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 14244f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(mBuffer, NULL); 14254f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 14264f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 14278a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber } 1428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 14294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC || mWantsNALFragments) { 14304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (newBuffer) { 14314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ssize_t num_bytes_read = 14329a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 14334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (num_bytes_read < (ssize_t)size) { 14354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 14364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 14374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 14394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 14404f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1441ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 14424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, size); 14434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->clear(); 1444fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 1445fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 14464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ++mCurrentSampleIndex; 14474f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 14484f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14494f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC) { 14504f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = mBuffer; 14514f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 14524f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 14544f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 14554f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Each NAL unit is split up into its constituent fragments and 14574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // each one of them returned in its own buffer. 14584f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1459db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 14604f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber const uint8_t *src = 14624f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 14634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1464db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t nal_size = parseNALSize(src); 1465909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1466909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber LOGE("incomplete NAL unit."); 1467909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1468909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer->release(); 1469909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer = NULL; 1470909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1471909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber return ERROR_MALFORMED; 1472909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber } 14734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber MediaBuffer *clone = mBuffer->clone(); 1475ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(clone != NULL); 1476db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 14774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1478ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 14794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range( 1480db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 1481db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 14824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer->range_length() == 0) { 14844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 14854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 14864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 14874f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = clone; 14894f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 14904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 14914f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } else { 14924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Whole NAL units are returned but each fragment is prefixed by 14934f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // the start code (0x00 00 00 01). 14944f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t num_bytes_read = 14969a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 1497e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1498e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (num_bytes_read < (ssize_t)size) { 1499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1500e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 1503e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 15064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t srcOffset = 0; 15074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t dstOffset = 0; 1508db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 15094f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber while (srcOffset < size) { 1510db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(srcOffset + mNALLengthSize <= size); 1511db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1512db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber srcOffset += mNALLengthSize; 1513909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1514909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber if (srcOffset + nalLength > size) { 1515909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer->release(); 1516909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer = NULL; 1517909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 1518909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber return ERROR_MALFORMED; 1519909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber } 15204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 15214f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (nalLength == 0) { 15224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber continue; 15234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 15244f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 15254f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 15264f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 15274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 15284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 15294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 15304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 1; 15314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 15324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber srcOffset += nalLength; 15334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstOffset += nalLength; 15344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 1535db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK_EQ(srcOffset, size); 15364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 1537ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 15384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, dstOffset); 1539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->clear(); 1540fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 1541fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++mCurrentSampleIndex; 1543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = mBuffer; 1545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1548e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1549e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1550e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1551be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMPEG4( 1552be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1553e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t header[8]; 1554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 15559a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 1556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < (ssize_t)sizeof(header)) { 1557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 1558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 15616bce6d87b3fd98e68fb54328fb4dc8e40cd2c293Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 156201830a0814ae2db9141f49720d9e5aa2457854f0Andreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)) { 1563e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *confidence = 0.1; 1565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 1567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 1570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 1573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1574