MPEG4Extractor.cpp revision 90ba107fcf36ce6df111a594b2cc27163b36793d
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" 22c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang#include "include/ESDS.h" 2313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang#include "timedtext/TimedTextPlayer.h" 24bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber 25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <arpa/inet.h> 26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <ctype.h> 28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdint.h> 29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h> 30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h> 31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 32940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/DataSource.h> 34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h> 35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 36e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h> 37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h> 38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h> 39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h> 40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h> 41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android { 43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MPEG4Source : public MediaSource { 45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic: 46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 47be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber MPEG4Source(const sp<MetaData> &format, 48be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 49fa8de752507feaca695123911915070c1ce463b2Andreas Huber int32_t timeScale, 50be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable); 51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t start(MetaData *params = NULL); 53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t stop(); 54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual sp<MetaData> getFormat(); 56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t read( 58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 60be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected: 61be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber virtual ~MPEG4Source(); 62be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber 63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate: 64ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex mLock; 65ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber sp<MetaData> mFormat; 67be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber sp<DataSource> mDataSource; 68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t mTimescale; 69be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber sp<SampleTable> mSampleTable; 70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t mCurrentSampleIndex; 71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mIsAVC; 73db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t mNALLengthSize; 74db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mStarted; 76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBufferGroup *mGroup; 78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer *mBuffer; 80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool mWantsNALFragments; 82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 838a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber uint8_t *mSrcBuffer; 848a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 85db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t parseNALSize(const uint8_t *data) const; 86db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source(const MPEG4Source &); 88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}; 90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 91affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// This custom data source wraps an existing one and satisfies requests 92affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// falling entirely within a cached range from the cache while forwarding 93affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// all remaining requests to the wrapped datasource. 94affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// This is used to cache the full sampletable metadata for a single track, 95affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// possibly wrapping multiple times to cover all tracks, i.e. 96affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track. 97affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 98affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstruct MPEG4DataSource : public DataSource { 99affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber MPEG4DataSource(const sp<DataSource> &source); 100affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 101affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual status_t initCheck() const; 102b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong virtual ssize_t readAt(off64_t offset, void *data, size_t size); 103b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong virtual status_t getSize(off64_t *size); 104affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual uint32_t flags(); 105affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 106b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong status_t setCachedRange(off64_t offset, size_t size); 107affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 108affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberprotected: 109affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber virtual ~MPEG4DataSource(); 110affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 111affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberprivate: 112affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber Mutex mLock; 113affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 114affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber sp<DataSource> mSource; 115b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t mCachedOffset; 116affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber size_t mCachedSize; 117affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber uint8_t *mCache; 118affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 119affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber void clearCache(); 120affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 121affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber MPEG4DataSource(const MPEG4DataSource &); 122affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber MPEG4DataSource &operator=(const MPEG4DataSource &); 123affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}; 124affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 125affa99c52957685f5a5652ab5254b92e729651c7Andreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 126affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber : mSource(source), 127affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedOffset(0), 128affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedSize(0), 129affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCache(NULL) { 130affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 131affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 132affa99c52957685f5a5652ab5254b92e729651c7Andreas HuberMPEG4DataSource::~MPEG4DataSource() { 133affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber clearCache(); 134affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 135affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 136affa99c52957685f5a5652ab5254b92e729651c7Andreas Hubervoid MPEG4DataSource::clearCache() { 137affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (mCache) { 138affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber free(mCache); 139affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCache = NULL; 140affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 141affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 142affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedOffset = 0; 143affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedSize = 0; 144affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 145affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 146affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::initCheck() const { 147affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->initCheck(); 148affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 149affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 150b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 151affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber Mutex::Autolock autoLock(mLock); 152affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 153affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (offset >= mCachedOffset 154affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber && offset + size <= mCachedOffset + mCachedSize) { 155affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber memcpy(data, &mCache[offset - mCachedOffset], size); 156affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return size; 157affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 158affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 159affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->readAt(offset, data, size); 160affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 161affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 162b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongstatus_t MPEG4DataSource::getSize(off64_t *size) { 163affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->getSize(size); 164affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 165affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 166affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberuint32_t MPEG4DataSource::flags() { 167affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return mSource->flags(); 168affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 169affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 170b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongstatus_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 171affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber Mutex::Autolock autoLock(mLock); 172affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 173affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber clearCache(); 174affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 175affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCache = (uint8_t *)malloc(size); 176affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 177affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (mCache == NULL) { 178affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return -ENOMEM; 179affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 180affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 181affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedOffset = offset; 182affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mCachedSize = size; 183affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 184affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 185affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 186affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (err < (ssize_t)size) { 187affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber clearCache(); 188affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 189affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return ERROR_IO; 190affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 191affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 192affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber return OK; 193affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber} 194affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 195affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 196affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void hexdump(const void *_data, size_t size) { 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const uint8_t *data = (const uint8_t *)_data; 199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t offset = 0; 200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (offset < size) { 201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("0x%04x ", offset); 202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t n = size - offset; 204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n > 16) { 205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber n = 16; 206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < 16; ++i) { 209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (i == 8) { 210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (offset + i < size) { 214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%02x ", data[offset + i]); 215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < n; ++i) { 223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (isprint(data[offset + i])) { 224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%c", data[offset + i]); 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("."); 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("\n"); 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber offset += 16; 233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 235e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 236e6c409632f773e41f33188272a0072be9fcb783fAndreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch (fourcc) { 238e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 239e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 241e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 242e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 243e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2442a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 245e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 2462a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 248e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 2510efdc95d59a51a130ce9d2515bcc9e2c01b52f14James Dong case FOURCC('h', '2', '6', '3'): 2520efdc95d59a51a130ce9d2515bcc9e2c01b52f14James Dong case FOURCC('H', '2', '6', '3'): 253e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 256e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 2594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!"should not be here."); 260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 261e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 264be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mDataSource(source), 266f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber mInitCheck(NO_INIT), 2671cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber mHasVideo(false), 268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack(NULL), 269c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mLastTrack(NULL), 270d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mFileMetaData(new MetaData), 271d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mFirstSINF(NULL), 272d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mIsDrm(false) { 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *next = track->next; 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete track; 281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = next; 282e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = mLastTrack = NULL; 284d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 285d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang SINF *sinf = mFirstSINF; 286d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while (sinf) { 287d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang SINF *next = sinf->next; 288d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang delete sinf->IPMPData; 289d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang delete sinf; 290d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf = next; 291d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 292d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mFirstSINF = NULL; 293e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2951cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 2961cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber status_t err; 2971cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber if ((err = readMetaData()) != OK) { 298c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return new MetaData; 2991cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber } 3001cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 301c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return mFileMetaData; 3021cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber} 3031cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 304be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MPEG4Extractor::countTracks() { 305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 306e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 307be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return 0; 308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 310be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber size_t n = 0; 311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 313be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber ++n; 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 317be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return n; 318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 320e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 321e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber size_t index, uint32_t flags) { 322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 329e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 330e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 332e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 333e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 334e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 335e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 336e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 3372a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 3382a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 3392a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 3402a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 341e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if ((flags & kIncludeExtensiveMetaData) 342e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber && !track->includes_expensive_metadata) { 343e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->includes_expensive_metadata = true; 344e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 345e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber const char *mime; 346e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 347e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (!strncasecmp("video/", mime, 6)) { 348e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber uint32_t sampleIndex; 349e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber uint32_t sampleTime; 350e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 3511faa92a1e93f311e86dca483ed7702091137de66Andreas Huber && track->sampleTable->getMetaDataForSample( 3521faa92a1e93f311e86dca483ed7702091137de66Andreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 3531faa92a1e93f311e86dca483ed7702091137de66Andreas Huber &sampleTime) == OK) { 354e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->meta->setInt64( 355e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber kKeyThumbnailTime, 356e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 357e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 358e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 359e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 360e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return track->meta; 362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 365f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber if (mInitCheck != NO_INIT) { 366f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber return mInitCheck; 367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 369b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t offset = 0; 370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 3731cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 374f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber if (mInitCheck == OK) { 375c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mHasVideo) { 376c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 377c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 378c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 379c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 380c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 38144fdac0c62916ddcfac1fe887d867e7ff0cf446fAndreas Huber mInitCheck = OK; 382f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber } else { 383f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber mInitCheck = err; 384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 386f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber CHECK_NE(err, (status_t)NO_INIT); 387f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber return mInitCheck; 388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 390d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 391d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mFirstSINF == NULL) { 392d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return NULL; 393d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 394d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 395d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang SINF *sinf = mFirstSINF; 396d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while (sinf && (trackID != sinf->trackID)) { 397d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf = sinf->next; 398d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 399d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 400d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (sinf == NULL) { 401d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return NULL; 402d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 403d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 404d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang *len = sinf->len; 405d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return sinf->IPMPData; 406d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang} 407d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 408d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 409b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongint32_t readSize(off64_t offset, 410d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang const sp<DataSource> DataSource, uint8_t *numOfBytes) { 411d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint32_t size = 0; 412d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t data; 413d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang bool moreData = true; 414d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang *numOfBytes = 0; 415d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 416d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while (moreData) { 417d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (DataSource->readAt(offset, &data, 1) < 1) { 418d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return -1; 419d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 420d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang offset ++; 421d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang moreData = (data >= 128) ? true : false; 422d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang size = (size << 7) | (data & 0x7f); // Take last 7 bits 423d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang (*numOfBytes) ++; 424d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 425d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 426d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return size; 427d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang} 428d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 429b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongstatus_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { 430d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t updateIdTag; 431d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 432d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 433d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 434d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset ++; 435d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 436d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 437d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 438d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 439d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 440d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t numOfBytes; 441d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 442d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (size < 0) { 443d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 444d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 445d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang int32_t classSize = size; 446d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset += numOfBytes; 447d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 448d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while(size >= 11 ) { 449d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t descriptorTag; 450d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 451d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 452d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 453d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset ++; 454d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 455d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 456d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 457d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 458d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 459d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t buffer[8]; 460d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang //ObjectDescriptorID and ObjectDescriptor url flag 461d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 462d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 463d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 464d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset += 2; 465d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 466d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if ((buffer[1] >> 5) & 0x0001) { //url flag is set 467d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 468d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 469d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 470d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 471d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 472d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 473d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset += 8; 474d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 475d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 476d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 477d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 478d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 479d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 480d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang SINF *sinf = new SINF; 481d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf->trackID = U16_AT(&buffer[3]); 482d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf->IPMPDescriptorID = buffer[7]; 483d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf->next = mFirstSINF; 484d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mFirstSINF = sinf; 485d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 486d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang size -= (8 + 2 + 1); 487d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 488d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 489d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (size != 0) { 490d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 491d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 492d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 493d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 494d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 495d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 496d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset ++; 497d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 498d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 499d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 500d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 501d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 502d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang size = readSize(data_offset, mDataSource, &numOfBytes); 503d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (size < 0) { 504d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 505d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 506d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang classSize = size; 507d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset += numOfBytes; 508d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 509d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while (size > 0) { 510d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t tag; 511d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang int32_t dataLen; 512d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 513d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 514d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 515d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset ++; 516d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 517d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 518d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t id; 519d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang dataLen = readSize(data_offset, mDataSource, &numOfBytes); 520d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (dataLen < 0) { 521d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 522d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } else if (dataLen < 4) { 523d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 524d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 525d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset += numOfBytes; 526d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 527d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset, &id, 1) < 1) { 528d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 529d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 530d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset ++; 531d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 532d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang SINF *sinf = mFirstSINF; 533d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while (sinf && (sinf->IPMPDescriptorID != id)) { 534d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf = sinf->next; 535d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 536d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (sinf == NULL) { 537d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 538d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 539d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf->len = dataLen - 3; 540d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang sinf->IPMPData = new char[sinf->len]; 541d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 542d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { 543d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_IO; 544d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 545d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang data_offset += sinf->len; 546d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 547d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang size -= (dataLen + numOfBytes + 1); 548d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 549d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 550d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 551d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (size != 0) { 552d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 553d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 554d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 555d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return UNKNOWN_ERROR; // Return a dummy error. 556d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang} 557d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[0] = x >> 24; 560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[1] = (x >> 16) & 0xff; 561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[2] = (x >> 8) & 0xff; 562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[3] = x & 0xff; 563e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[4] = '\0'; 564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 566c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstruct PathAdder { 567c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 568c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber : mPath(path) { 569c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mPath->push(chunkType); 570c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 571c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 572c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber ~PathAdder() { 573c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mPath->pop(); 574c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 575c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 576c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberprivate: 577c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber Vector<uint32_t> *mPath; 578c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 579c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder(const PathAdder &); 580c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder &operator=(const PathAdder &); 581c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber}; 582c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 583c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 584c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return path.size() >= 5 585c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 586c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 587c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 588c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 589c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 590c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 591c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 592c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 593c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 594c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 595c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char tmp[32]; 596c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 597c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 598c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber s->setTo(tmp); 599c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 600c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 601b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongstatus_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t hdr[2]; 6039a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 608b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t data_offset = *offset + 8; 609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size == 1) { 6119a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_size = ntoh64(chunk_size); 615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset += 8; 616736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber 617736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber if (chunk_size < 16) { 618736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber // The smallest valid chunk is 16 bytes long in this case. 619736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber return ERROR_MALFORMED; 620736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber } 621736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber } else if (chunk_size < 8) { 622736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber // The smallest valid chunk is 8 bytes long. 623736c22d3e0b96a45e46ce43ac20a48ecbc373db7Andreas Huber return ERROR_MALFORMED; 624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char chunk[5]; 627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MakeFourCCString(chunk_type, chunk); 628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0 630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber static const char kWhitespace[] = " "; 631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 635dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber size_t n = chunk_size; 636dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber if (n > sizeof(buffer)) { 637dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber n = sizeof(buffer); 638dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber } 639dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber if (mDataSource->readAt(*offset, buffer, n) 640dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber < (ssize_t)n) { 641dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber return ERROR_IO; 642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 643dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber 644dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber hexdump(buffer, n); 645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif 646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 647c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 648c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 649b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t chunk_data_size = *offset + chunk_size - data_offset; 650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 651c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 652e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong && chunk_type != FOURCC('c', 'o', 'v', 'r') 653c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 654b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t stop_offset = *offset + chunk_size; 655c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset = data_offset; 656c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber while (*offset < stop_offset) { 657c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseChunk(offset, depth + 1); 658c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 659c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 660c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 661c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 6625ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 6635ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 6645ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 6655ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 666c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 667c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return OK; 668c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 669c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch(chunk_type) { 671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'b', 'l'): 677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 681c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('u', 'd', 't', 'a'): 682c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('i', 'l', 's', 't'): 683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 684affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 685affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 686affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 6876da2ae11b62f155ee83c3e31fdd9cc53b2058586Andreas Huber if (mDataSource->flags() 6886da2ae11b62f155ee83c3e31fdd9cc53b2058586Andreas Huber & (DataSource::kWantsPrefetching 6896da2ae11b62f155ee83c3e31fdd9cc53b2058586Andreas Huber | DataSource::kIsCachingDataSource)) { 690affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber sp<MPEG4DataSource> cachedSource = 691affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber new MPEG4DataSource(mDataSource); 692affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 693affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 694affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber mDataSource = cachedSource; 695affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 696affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 697eb9128f9b0ee660504621381fd96f82d5bf8a3fdAndreas Huber 698eb9128f9b0ee660504621381fd96f82d5bf8a3fdAndreas Huber mLastTrack->sampleTable = new SampleTable(mDataSource); 699affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber } 700affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber 7014d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber bool isTrack = false; 7025ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 7034d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber isTrack = true; 7044d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 7055ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber Track *track = new Track; 7065ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->next = NULL; 7075ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (mLastTrack) { 7085ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber mLastTrack->next = track; 7095ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else { 7105ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber mFirstTrack = track; 7115ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 7125ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber mLastTrack = track; 7135ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 7145ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->meta = new MetaData; 7155ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->includes_expensive_metadata = false; 7164d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber track->skipTrack = false; 7175ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->timescale = 0; 7185ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 7195ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 7205ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 721b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t stop_offset = *offset + chunk_size; 722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset; 723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 727e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 728e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 7315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 7325ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 7335ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 7344d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber if (isTrack) { 7354d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber if (mLastTrack->skipTrack) { 7364d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber Track *cur = mFirstTrack; 7374d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 7384d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber if (cur == mLastTrack) { 7394d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber delete cur; 7404d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber mFirstTrack = mLastTrack = NULL; 7414d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } else { 7424d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber while (cur && cur->next != mLastTrack) { 7434d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber cur = cur->next; 7444d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } 7454d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber cur->next = NULL; 7464d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber delete mLastTrack; 7474d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber mLastTrack = cur; 7484d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } 7494d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 7504d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber return OK; 7514d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber } 7524d60fc5b43b74cdb45e1d1ba55972d48ebed37eeAndreas Huber 7535ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber status_t err = verifyTrack(mLastTrack); 7545ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 7555ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (err != OK) { 7565ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return err; 7575ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 7585ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 759f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber mInitCheck = OK; 760e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 761d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (!mIsDrm) { 762d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return UNKNOWN_ERROR; // Return a dummy error. 763d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } else { 764d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return OK; 765d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 766e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 767e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 768e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 769e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 770e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 771e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 772940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber status_t err; 773940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 774940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber return err; 775e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 776e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 777e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 778e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 779e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 780e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 781e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 783e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 784e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 785e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 786e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 7889a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 789e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, &version, sizeof(version)) 790e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(version)) { 791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 793e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 794b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t timescale_offset; 795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 796e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 797e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 16; 798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 8; 800e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 801e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 802e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 803e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 804e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t timescale; 8059a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(timescale)) { 808e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 810e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->timescale = ntohl(timescale); 812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 813e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t duration; 814e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 8159a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration)) { 818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 819e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 820e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntoh64(duration); 821e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 822e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t duration32; 8239a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration32)) { 826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 827e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 828e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntohl(duration32); 829e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 830fa8de752507feaca695123911915070c1ce463b2Andreas Huber mLastTrack->meta->setInt64( 831fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 832e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 833c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang uint8_t lang[2]; 834c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang off64_t lang_offset; 835c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang if (version == 1) { 836c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang lang_offset = timescale_offset + 4 + 8; 837c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } else if (version == 0) { 838c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang lang_offset = timescale_offset + 4 + 4; 839c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } else { 840c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang return ERROR_IO; 841c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 842c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 843c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 844c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang < (ssize_t)sizeof(lang)) { 845c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang return ERROR_IO; 846c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 847c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 848c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang // To get the ISO-639-2/T three character language code 849c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang // 1 bit pad followed by 3 5-bits characters. Each character 850c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang // is packed as the difference between its ASCII value and 0x60. 851c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang char lang_code[4]; 852c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 853c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 854c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang lang_code[2] = (lang[1] & 0x1f) + 0x60; 855c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang lang_code[3] = '\0'; 856c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 857c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang mLastTrack->meta->setCString( 858c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang kKeyMediaLanguage, lang_code); 859c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 861e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 862e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 863e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 864e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'd'): 865e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 866e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 8) { 867e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 868e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 869e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 870e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8]; 871b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 8725ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 8735ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 8745ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 8759a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 876e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, 8) < 8) { 877e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 878e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 879e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 880e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 881e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 882e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 883e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 884e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 885e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 886e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 887e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (entry_count > 1) { 888eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang // For 3GPP timed text, there could be multiple tx3g boxes contain 889eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang // multiple text display formats. These formats will be used to 890eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang // display the timed text. 891eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang const char *mime; 892eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 893eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { 894eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang // For now we only support a single type of media per track. 895eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang mLastTrack->skipTrack = true; 896eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang *offset += chunk_size; 897eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang break; 898eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 899e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 900e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 901b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t stop_offset = *offset + chunk_size; 902e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + 8; 903e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 904e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 905e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 906e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 907e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 908e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 9095ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 9105ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 9115ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 9125ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 913e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 914e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 915e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 916e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 917e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 9182a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 919e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 920e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8 + 20]; 921e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 922e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic AudioSampleEntry size. 923e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 924e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 925e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9269a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 927e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 928e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 929e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 930e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 931e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 932e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 933e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 934d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 935d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 936d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 937e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 938d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber FourCC2MIME(chunk_type))) { 939d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber // AMR NB audio is always mono, 8kHz 940d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber num_channels = 1; 941d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber sample_rate = 8000; 942d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 943e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber FourCC2MIME(chunk_type))) { 944d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber // AMR WB audio is always mono, 16kHz 945e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber num_channels = 1; 946d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber sample_rate = 16000; 947e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 948e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 949d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber#if 0 950d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 951d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber chunk, num_channels, sample_size, sample_rate); 952d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber#endif 953e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 954e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 955e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 956e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 957e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 958b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t stop_offset = *offset + chunk_size; 959e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 960e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 961e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 962e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 963e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 964e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 965e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 9665ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 9675ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 9685ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 9695ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 970e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 971e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 972e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 973e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 974e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 9750efdc95d59a51a130ce9d2515bcc9e2c01b52f14James Dong case FOURCC('H', '2', '6', '3'): 9760efdc95d59a51a130ce9d2515bcc9e2c01b52f14James Dong case FOURCC('h', '2', '6', '3'): 977e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 978e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 9791cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber mHasVideo = true; 9801cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber 981e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[78]; 982e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 983e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic VideoSampleEntry size. 984e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 985e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 986e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9879a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 988e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 989e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 990e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 991e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 992e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 993e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 994e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 995e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 996c9e1c80f786667e264748bf2843dabdc2029c006James Dong // The video sample is not stand-compliant if it has invalid dimension. 997c9e1c80f786667e264748bf2843dabdc2029c006James Dong // Use some default width and height value, and 998c9e1c80f786667e264748bf2843dabdc2029c006James Dong // let the decoder figure out the actual width and height (and thus 999c9e1c80f786667e264748bf2843dabdc2029c006James Dong // be prepared for INFO_FOMRAT_CHANGED event). 1000c9e1c80f786667e264748bf2843dabdc2029c006James Dong if (width == 0) width = 352; 1001c9e1c80f786667e264748bf2843dabdc2029c006James Dong if (height == 0) height = 288; 1002c9e1c80f786667e264748bf2843dabdc2029c006James Dong 10032ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // printf("*** coding='%s' width=%d height=%d\n", 10042ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber // chunk, width, height); 1005e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1006e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1007e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 1008e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 1009e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1010b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t stop_offset = *offset + chunk_size; 1011e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 1012e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 1013e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 1014e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1015e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1016e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1017e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 10185ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 10195ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 10205ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 10215ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 1022e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1023e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1024e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1025e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'c', 'o'): 1026e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('c', 'o', '6', '4'): 1027e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1028e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 1029e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 1030e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 1031e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1032e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1033e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1034e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1035e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1036e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1037e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1038e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1039e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1040e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'c'): 1041e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1042e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 1043e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 1044e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 1045e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1046e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1047e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1048e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1049e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1050e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1051e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1052e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1053e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1054e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'z'): 1055e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'z', '2'): 1056e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1057e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 1058e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 1059e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 1060e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1061e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1062e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1063e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1064e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 10651bceff916a72246fa208605d50615823d7f1688bAndreas Huber size_t max_size; 1066d7f2225e7455f5e0da32f409a528ced283631c5dAndreas Huber err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 1067d7f2225e7455f5e0da32f409a528ced283631c5dAndreas Huber 1068d7f2225e7455f5e0da32f409a528ced283631c5dAndreas Huber if (err != OK) { 1069d7f2225e7455f5e0da32f409a528ced283631c5dAndreas Huber return err; 1070d7f2225e7455f5e0da32f409a528ced283631c5dAndreas Huber } 10711bceff916a72246fa208605d50615823d7f1688bAndreas Huber 10721bceff916a72246fa208605d50615823d7f1688bAndreas Huber // Assume that a given buffer only contains at most 10 fragments, 10731bceff916a72246fa208605d50615823d7f1688bAndreas Huber // each fragment originally prefixed with a 2 byte length will 10741bceff916a72246fa208605d50615823d7f1688bAndreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 10751bceff916a72246fa208605d50615823d7f1688bAndreas Huber // and thus will grow by 2 bytes per fragment. 10761bceff916a72246fa208605d50615823d7f1688bAndreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 1077e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1078cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong 1079cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong // Calculate average frame rate. 1080cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong const char *mime; 1081cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1082cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong if (!strncasecmp("video/", mime, 6)) { 1083cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong size_t nSamples = mLastTrack->sampleTable->countSamples(); 1084cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong int64_t durationUs; 1085cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1086cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong if (durationUs > 0) { 1087cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong int32_t frameRate = (nSamples * 1000000LL + 1088cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong (durationUs >> 1)) / durationUs; 1089cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1090cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong } 1091cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong } 1092cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong } 1093cbb488d67826dd38f665bc8626b55dfe2f0e135fJames Dong 1094e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1095e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1096e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1097e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 't', 's'): 1098e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1099e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 1100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 1101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 1102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1111bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber case FOURCC('c', 't', 't', 's'): 1112bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber { 1113bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber status_t err = 1114bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber mLastTrack->sampleTable->setCompositionTimeToSampleParams( 1115bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber data_offset, chunk_data_size); 1116bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber 1117bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber if (err != OK) { 1118bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber return err; 1119bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber } 1120bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber 1121bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber *offset += chunk_size; 1122bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber break; 1123bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber } 1124bd352c3cdc6a8682dae58a5108c82a303be05274Andreas Huber 1125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 's'): 1126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 1128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 1129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 1130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('e', 's', 'd', 's'): 1140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 1142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 1143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[256]; 1146b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 1147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 1148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 11509a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 1151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 1152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 1153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1155e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 1156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 1157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 1158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1160e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 1161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 1162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1163d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (mPath.size() >= 2 1164d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1165d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // Information from the ESDS must be relied on for proper 1166d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // setup of sample rate and channel count for MPEG4 Audio. 1167d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // The generic header appears to only contain generic 1168d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber // information... 1169d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1170d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1171d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber &buffer[4], chunk_data_size - 4); 1172d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1173d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (err != OK) { 1174d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return err; 1175d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1176d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1177d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1179e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1181e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1182e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 1183e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1184e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 1185b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong if (chunk_data_size > (off64_t)sizeof(buffer)) { 1186e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 1187e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1188e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 11899a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber if (mDataSource->readAt( 1190e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 1191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 1192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 1195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 1196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1201fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong case FOURCC('d', '2', '6', '3'): 1202fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong { 1203bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong /* 1204bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * d263 contains a fixed 7 bytes part: 1205bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * vendor - 4 bytes 1206bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * version - 1 byte 1207bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * level - 1 byte 1208bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * profile - 1 byte 1209bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * optionally, "d263" box itself may contain a 16-byte 1210bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * bit rate box (bitr) 1211bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * average bit rate - 4 bytes 1212bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong * max bit rate - 4 bytes 1213bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong */ 1214bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong char buffer[23]; 1215bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong if (chunk_data_size != 7 && 1216bc5f1f5c815e6a158859c031fa7bb0fd68d973b9James Dong chunk_data_size != 23) { 1217fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong LOGE("Incorrect D263 box size %lld", chunk_data_size); 1218fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong return ERROR_MALFORMED; 1219fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong } 1220fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong 1221fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong if (mDataSource->readAt( 1222fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong data_offset, buffer, chunk_data_size) < chunk_data_size) { 1223fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong return ERROR_IO; 1224fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong } 1225fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong 1226fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1227fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong 1228fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong *offset += chunk_size; 1229fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong break; 1230fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong } 1231fe84cf13cdbccec4a499caca05f0dc309df9d318James Dong 1232c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('m', 'e', 't', 'a'): 1233c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1234c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t buffer[4]; 1235b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong if (chunk_data_size < (off64_t)sizeof(buffer)) { 12365ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 12375ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 12385ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 1239c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 1240c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber data_offset, buffer, 4) < 4) { 1241c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 1242c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1243c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1244c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (U32_AT(buffer) != 0) { 1245c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber // Should be version 0, flags 0. 1246dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber 1247dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // If it's not, let's assume this is one of those 1248dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // apparently malformed chunks that don't have flags 1249dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // and completely different semantics than what's 1250dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber // in the MPEG4 specs and skip it. 1251dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber *offset += chunk_size; 1252dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber return OK; 1253c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1254c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1255b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t stop_offset = *offset + chunk_size; 1256c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset = data_offset + sizeof(buffer); 1257c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber while (*offset < stop_offset) { 1258c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseChunk(offset, depth + 1); 1259c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 1260c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 1261c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1262c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 12635ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 12645ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (*offset != stop_offset) { 12655ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 12665ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 1267c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1268c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1269c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1270c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('d', 'a', 't', 'a'): 1271c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1272c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1273c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 1274c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1275c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (err != OK) { 1276c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return err; 1277c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1278c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1279c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1280c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset += chunk_size; 1281c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1282c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1283c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1284c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 1285c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1286c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (chunk_data_size < 12) { 1287c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 1288c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1289c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1290c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t header[12]; 1291c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 1292c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber data_offset, header, sizeof(header)) 1293c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber < (ssize_t)sizeof(header)) { 1294c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 1295c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1296c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1297c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber int64_t creationTime; 1298c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (header[0] == 1) { 1299c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber creationTime = U64_AT(&header[4]); 13005ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else if (header[0] != 0) { 13015ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 1302c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 1303c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber creationTime = U32_AT(&header[4]); 1304c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1305c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1306c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber String8 s; 1307c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber convertTimeToDate(creationTime, &s); 1308c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1309c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 1310c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1311c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber *offset += chunk_size; 1312c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1313c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1314c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1315d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang case FOURCC('m', 'd', 'a', 't'): 1316d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang { 1317d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (!mIsDrm) { 1318d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang *offset += chunk_size; 1319d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang break; 1320d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 1321d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 1322d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (chunk_size < 8) { 1323d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 1324d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 1325d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 1326d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return parseDrmSINF(offset, data_offset); 1327d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 1328d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 1329eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang case FOURCC('h', 'd', 'l', 'r'): 1330eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang { 1331eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang uint32_t buffer; 1332eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang if (mDataSource->readAt( 1333eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang data_offset + 8, &buffer, 4) < 4) { 1334eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang return ERROR_IO; 1335eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 1336eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1337eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang uint32_t type = ntohl(buffer); 1338eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang // For the 3GPP file format, the handler-type within the 'hdlr' box 1339eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang // shall be 'text' 1340eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang if (type == FOURCC('t', 'e', 'x', 't')) { 1341eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 1342eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 1343eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1344eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang *offset += chunk_size; 1345eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang break; 1346eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 1347eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1348c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang case FOURCC('t', 'x', '3', 'g'): 1349c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang { 1350eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang uint32_t type; 1351eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang const void *data; 1352eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang size_t size = 0; 1353eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang if (!mLastTrack->meta->findData( 1354eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang kKeyTextFormatData, &type, &data, &size)) { 1355eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang size = 0; 1356eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 1357eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1358eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang uint8_t *buffer = new uint8_t[size + chunk_size]; 1359eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1360eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang if (size > 0) { 1361eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang memcpy(buffer, data, size); 1362eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 1363eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1364eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 1365eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang < chunk_size) { 1366eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang delete[] buffer; 1367eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang buffer = NULL; 1368eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1369eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang return ERROR_IO; 1370eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 1371eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1372eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang mLastTrack->meta->setData( 1373eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang kKeyTextFormatData, 0, buffer, size + chunk_size); 1374eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang 1375eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang delete[] buffer; 1376c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 1377c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang *offset += chunk_size; 1378c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang break; 1379c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 1380c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 1381e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong case FOURCC('c', 'o', 'v', 'r'): 1382e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong { 1383e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong if (mFileMetaData != NULL) { 1384e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong LOGV("chunk_data_size = %lld and data_offset = %lld", 1385e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong chunk_data_size, data_offset); 1386e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong uint8_t *buffer = new uint8_t[chunk_data_size + 1]; 1387e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong if (mDataSource->readAt( 1388e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) { 1389e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong delete[] buffer; 1390e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong buffer = NULL; 1391e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong 1392e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong return ERROR_IO; 1393e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong } 1394e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong const int kSkipBytesOfDataBox = 16; 1395e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong mFileMetaData->setData( 1396e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong kKeyAlbumArt, MetaData::TYPE_NONE, 1397e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1398e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong } 1399e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong 1400e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong *offset += chunk_size; 1401e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong break; 1402e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong } 1403e8b26dcec7765786bbf063b3ae6b967b8b547ab6James Dong 1404e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 1405e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 1406e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 1407e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 1408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1414940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader( 1415b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t data_offset, off64_t data_size) { 1416940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if (data_size < 4) { 1417940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber return ERROR_MALFORMED; 1418940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1419940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1420940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber uint8_t version; 1421940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1422940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber return ERROR_IO; 1423940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1424940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1425940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber size_t dynSize = (version == 1) ? 36 : 24; 1426940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1427940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber uint8_t buffer[36 + 60]; 1428940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1429b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong if (data_size != (off64_t)dynSize + 60) { 1430940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber return ERROR_MALFORMED; 1431940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1432940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1433940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if (mDataSource->readAt( 1434940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber data_offset, buffer, data_size) < (ssize_t)data_size) { 1435940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber return ERROR_IO; 1436940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1437940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1438940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber uint64_t ctime, mtime, duration; 1439940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t id; 1440940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1441940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if (version == 1) { 1442940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber ctime = U64_AT(&buffer[4]); 1443940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber mtime = U64_AT(&buffer[12]); 1444940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber id = U32_AT(&buffer[20]); 1445940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber duration = U64_AT(&buffer[28]); 1446940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } else { 1447940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber CHECK_EQ((unsigned)version, 0u); 1448940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1449940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber ctime = U32_AT(&buffer[4]); 1450940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber mtime = U32_AT(&buffer[8]); 1451940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber id = U32_AT(&buffer[12]); 1452940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber duration = U32_AT(&buffer[20]); 1453940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1454940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1455940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber mLastTrack->meta->setInt32(kKeyTrackID, id); 1456940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1457940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber size_t matrixOffset = dynSize + 16; 1458940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t a00 = U32_AT(&buffer[matrixOffset]); 1459940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1460940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1461940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1462940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1463940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1464940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1465940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber#if 0 1466940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber LOGI("x' = %.2f * x + %.2f * y + %.2f", 1467940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1468940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber LOGI("y' = %.2f * x + %.2f * y + %.2f", 1469940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1470940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber#endif 1471940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1472940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber uint32_t rotationDegrees; 1473940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1474940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber static const int32_t kFixedOne = 0x10000; 1475940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1476940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber // Identity, no rotation 1477940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber rotationDegrees = 0; 1478940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1479940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber rotationDegrees = 90; 1480940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1481940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber rotationDegrees = 270; 1482940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1483940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber rotationDegrees = 180; 1484940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } else { 1485940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber LOGW("We only support 0,90,180,270 degree rotation matrices"); 1486940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber rotationDegrees = 0; 1487940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1488940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1489940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber if (rotationDegrees != 0) { 1490940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1491940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber } 1492940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 149308adfd29ae3634b554cfe184ab82f112ef934d7bJames Dong // Handle presentation display size, which could be different 149408adfd29ae3634b554cfe184ab82f112ef934d7bJames Dong // from the image size indicated by kKeyWidth and kKeyHeight. 1495940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber uint32_t width = U32_AT(&buffer[dynSize + 52]); 1496940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber uint32_t height = U32_AT(&buffer[dynSize + 56]); 149708adfd29ae3634b554cfe184ab82f112ef934d7bJames Dong mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 149808adfd29ae3634b554cfe184ab82f112ef934d7bJames Dong mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 1499940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1500940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber return OK; 1501940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber} 1502940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber 1503b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dongstatus_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 1504c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size < 4) { 1505c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_MALFORMED; 1506c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1507c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1508c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 1509c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (mDataSource->readAt( 1510c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber offset, buffer, size) != (ssize_t)size) { 1511c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber delete[] buffer; 1512c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer = NULL; 1513c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1514c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return ERROR_IO; 1515c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1516c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1517c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint32_t flags = U32_AT(buffer); 1518c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1519c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber uint32_t metadataKey = 0; 1520c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber switch (mPath[4]) { 1521c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 1522c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1523c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyAlbum; 1524c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1525c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1526c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 1527c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1528c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyArtist; 1529c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1530c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1531c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen case FOURCC('a', 'A', 'R', 'T'): 1532c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen { 1533c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen metadataKey = kKeyAlbumArtist; 1534c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen break; 1535c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen } 1536c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 1537c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1538c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyYear; 1539c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1540c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1541c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 1542c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1543c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyTitle; 1544c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1545c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1546c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 1547c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1548c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyWriter; 1549c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1550c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1551c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 1552c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1553c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyAlbumArt; 1554c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1555c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1556c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 1557c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1558c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey = kKeyGenre; 1559c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1560c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1561fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen case FOURCC(0xa9, 'g', 'e', 'n'): 1562fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen { 1563fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen metadataKey = kKeyGenre; 1564fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen break; 1565fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1566ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen case FOURCC('c', 'p', 'i', 'l'): 1567ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen { 1568ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen if (size == 9 && flags == 21) { 1569ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen char tmp[16]; 1570ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen sprintf(tmp, "%d", 1571ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen (int)buffer[size - 1]); 1572ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen 1573ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen mFileMetaData->setCString(kKeyCompilation, tmp); 1574ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen } 1575ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen break; 1576ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen } 1577c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 1578c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { 1579c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size == 16 && flags == 0) { 1580c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char tmp[16]; 1581c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber sprintf(tmp, "%d/%d", 1582c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 1583c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1584c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1585c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1586c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1587c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1588fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen case FOURCC('d', 'i', 's', 'k'): 1589fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen { 1590fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen if (size == 14 && flags == 0) { 1591fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen char tmp[16]; 1592fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen sprintf(tmp, "%d/%d", 1593fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen (int)buffer[size - 3], (int)buffer[size - 1]); 1594fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1595fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen mFileMetaData->setCString(kKeyDiscNumber, tmp); 1596fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1597fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen break; 1598fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1599fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1600c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber default: 1601c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber break; 1602c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1603c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1604c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (size >= 8 && metadataKey) { 1605c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (metadataKey == kKeyAlbumArt) { 1606c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setData( 1607c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 1608c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer + 8, size - 8); 1609c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else if (metadataKey == kKeyGenre) { 1610c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber if (flags == 0) { 1611fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // uint8_t genre code, iTunes genre codes are 1612fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // the standard id3 codes, except they start 1613fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // at 1 instead of 0 (e.g. Pop is 14, not 13) 1614fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // We use standard id3 numbering, so subtract 1. 1615fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen int genrecode = (int)buffer[size - 1]; 1616fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen genrecode--; 1617fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen if (genrecode < 0) { 1618fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen genrecode = 255; // reserved for 'unknown genre' 1619fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } 1620c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber char genre[10]; 1621fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen sprintf(genre, "%d", genrecode); 1622c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1623c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString(metadataKey, genre); 1624fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen } else if (flags == 1) { 1625fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen // custom genre string 1626fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen buffer[size] = '\0'; 1627fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen 1628fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen mFileMetaData->setCString( 1629fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen metadataKey, (const char *)buffer + 8); 1630c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1631c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } else { 1632c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer[size] = '\0'; 1633c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1634c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber mFileMetaData->setCString( 1635c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber metadataKey, (const char *)buffer + 8); 1636c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1637c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber } 1638c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1639c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber delete[] buffer; 1640c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber buffer = NULL; 1641c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1642c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber return OK; 1643c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber} 1644c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber 1645be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 1647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 1648be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 1649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 1652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 1653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 1654be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 1655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 1658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 1659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 16612a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 16622a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 16632a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 16642a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 1665be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return new MPEG4Source( 1666fa8de752507feaca695123911915070c1ce463b2Andreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 1667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 16695ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber// static 16705ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) { 16715ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber const char *mime; 16725ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 16735ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 16745ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber uint32_t type; 16755ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber const void *data; 16765ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber size_t size; 16775ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 16785ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 16795ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber || type != kTypeAVCC) { 16805ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 16815ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 16825ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 16835ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 16845ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber if (!track->meta->findData(kKeyESDS, &type, &data, &size) 16855ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber || type != kTypeESDS) { 16865ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return ERROR_MALFORMED; 16875ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 16885ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber } 16895ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 1690987cb2ed4a3aebdb624088c38981b2409ab8f6b1Andreas Huber if (!track->sampleTable->isValid()) { 1691987cb2ed4a3aebdb624088c38981b2409ab8f6b1Andreas Huber // Make sure we have all the metadata we need. 1692987cb2ed4a3aebdb624088c38981b2409ab8f6b1Andreas Huber return ERROR_MALFORMED; 1693987cb2ed4a3aebdb624088c38981b2409ab8f6b1Andreas Huber } 1694987cb2ed4a3aebdb624088c38981b2409ab8f6b1Andreas Huber 16955ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber return OK; 16965ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber} 16975ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber 1698d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1699d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber const void *esds_data, size_t esds_size) { 1700d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber ESDS esds(esds_data, esds_size); 1701d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 1702d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber uint8_t objectTypeIndication; 1703d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1704d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber return ERROR_MALFORMED; 1705d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber } 1706d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 1707d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber if (objectTypeIndication == 0xe1) { 1708d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber // This isn't MPEG4 audio at all, it's QCELP 14k... 1709d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 1710d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber return OK; 1711d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber } 1712d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber 1713e883d317d51733145b880ce11c610f0287fba447James Dong if (objectTypeIndication == 0x6b) { 1714e883d317d51733145b880ce11c610f0287fba447James Dong // The media subtype is MP3 audio 1715e883d317d51733145b880ce11c610f0287fba447James Dong // Our software MP3 audio decoder may not be able to handle 1716e883d317d51733145b880ce11c610f0287fba447James Dong // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 1717e883d317d51733145b880ce11c610f0287fba447James Dong LOGE("MP3 track in MP4/3GPP file is not supported"); 1718e883d317d51733145b880ce11c610f0287fba447James Dong return ERROR_UNSUPPORTED; 1719e883d317d51733145b880ce11c610f0287fba447James Dong } 1720e883d317d51733145b880ce11c610f0287fba447James Dong 1721d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber const uint8_t *csd; 1722d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber size_t csd_size; 1723d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (esds.getCodecSpecificInfo( 1724d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber (const void **)&csd, &csd_size) != OK) { 1725d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1726d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1727d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1728d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#if 0 1729d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber printf("ESD of size %d\n", csd_size); 1730d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber hexdump(csd, csd_size); 1731d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#endif 1732d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 173308c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber if (csd_size == 0) { 173408c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber // There's no further information, i.e. no codec specific data 173508c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber // Let's assume that the information provided in the mpeg4 headers 173608c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber // is accurate and hope for the best. 173708c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber 173808c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber return OK; 173908c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber } 174008c94b265c4bf7105b593afb119053a2e16865e9Andreas Huber 1741d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (csd_size < 2) { 1742d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1743d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1744d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1745d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber uint32_t objectType = csd[0] >> 3; 1746d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1747d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (objectType == 31) { 1748d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_UNSUPPORTED; 1749d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1750d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1751d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1752d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t sampleRate = 0; 1753d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t numChannels = 0; 1754d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (freqIndex == 15) { 1755d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (csd_size < 5) { 1756d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1757d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1758d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1759d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber sampleRate = (csd[1] & 0x7f) << 17 1760d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | csd[2] << 9 1761d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | csd[3] << 1 1762d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber | (csd[4] >> 7); 1763d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1764d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber numChannels = (csd[4] >> 3) & 15; 1765d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } else { 1766cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber static uint32_t kSamplingRate[] = { 1767cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1768cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber 16000, 12000, 11025, 8000, 7350 1769cc14a8393b92cd1ed6cba74829396045605ab211Andreas Huber }; 1770d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1771d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (freqIndex == 13 || freqIndex == 14) { 1772d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_MALFORMED; 1773d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1774d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1775d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber sampleRate = kSamplingRate[freqIndex]; 1776d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber numChannels = (csd[1] >> 3) & 15; 1777d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1778d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1779d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (numChannels == 0) { 1780d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return ERROR_UNSUPPORTED; 1781d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1782d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1783d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t prevSampleRate; 1784d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1785d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1786d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (prevSampleRate != sampleRate) { 17874a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber LOGV("mpeg4 audio sample rate different from previous setting. " 1788d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber "was: %d, now: %d", prevSampleRate, sampleRate); 1789d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1790d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1791d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1792d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1793d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber int32_t prevChannelCount; 1794d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1795d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1796d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber if (prevChannelCount != numChannels) { 17974a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber LOGV("mpeg4 audio channel count different from previous setting. " 1798d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber "was: %d, now: %d", prevChannelCount, numChannels); 1799d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber } 1800d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1801d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1802d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1803d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber return OK; 1804d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber} 1805d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber 1806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1808e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source( 1809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const sp<MetaData> &format, 1810be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 1811fa8de752507feaca695123911915070c1ce463b2Andreas Huber int32_t timeScale, 1812be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable) 1813e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mFormat(format), 1814e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mDataSource(dataSource), 1815fa8de752507feaca695123911915070c1ce463b2Andreas Huber mTimescale(timeScale), 1816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSampleTable(sampleTable), 1817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex(0), 1818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mIsAVC(false), 1819db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mNALLengthSize(0), 1820e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted(false), 1821e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup(NULL), 1822e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer(NULL), 18234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments(false), 18248a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer(NULL) { 1825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *mime; 1826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 18274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(success); 1828e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1829e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1830db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1831db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber if (mIsAVC) { 1832db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber uint32_t type; 1833db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber const void *data; 1834db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t size; 1835db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1836db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1837db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1838db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1839db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(size >= 7); 1840940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 1841db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1842db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // The number of bytes used to encode the length of a NAL unit. 1843db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 1844db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber } 1845e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1846e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1847e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() { 1848e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mStarted) { 1849e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber stop(); 1850e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1852e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1853e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 1854ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1855ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 18564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!mStarted); 1857e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1858e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t val; 18594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 1860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber && val != 0) { 18614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = true; 1862e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 18634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = false; 1864e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1865e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1866e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = new MediaBufferGroup; 1867e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 18681bceff916a72246fa208605d50615823d7f1688bAndreas Huber int32_t max_size; 18691bceff916a72246fa208605d50615823d7f1688bAndreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1870e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 18711bceff916a72246fa208605d50615823d7f1688bAndreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 18728a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 18738a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = new uint8_t[max_size]; 1874e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1875e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = true; 1876e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1877e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1878e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1879e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1880e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() { 1881ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1882ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 18834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 1884e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1885e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 1886e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 1887e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 1888e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1889e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 18908a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber delete[] mSrcBuffer; 18918a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = NULL; 18928a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 1893e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete mGroup; 1894e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = NULL; 1895e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1896e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = false; 1897e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = 0; 1898e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1899e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 1900e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1901e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1902e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 1903ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1904ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 1905e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return mFormat; 1906e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1907e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1908db5d662254f2ed788d32e2466739adc8d655c732Andreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1909db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber switch (mNALLengthSize) { 1910db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 1: 1911db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return *data; 1912db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 2: 1913db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return U16_AT(data); 1914db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 3: 1915db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1916db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber case 4: 1917db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return U32_AT(data); 1918db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber } 1919db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1920db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 1921db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber // a 2-bit integer. 1922db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(!"Should not be here."); 1923db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1924db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber return 0; 1925db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber} 1926db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 1927e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read( 1928e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **out, const ReadOptions *options) { 1929ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber Mutex::Autolock autoLock(mLock); 1930ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber 19314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 1932e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1933e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = NULL; 1934e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 19356624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber int64_t targetSampleTimeUs = -1; 19366624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 1937e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t seekTimeUs; 19386624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber ReadOptions::SeekMode mode; 19396624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 19406624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t findFlags = 0; 19416624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber switch (mode) { 19426624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_PREVIOUS_SYNC: 19436624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagBefore; 19446624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 19456624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_NEXT_SYNC: 19466624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagAfter; 19476624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 19486624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_CLOSEST_SYNC: 19496624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber case ReadOptions::SEEK_CLOSEST: 19506624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagClosest; 19516624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 19526624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber default: 19536624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber CHECK(!"Should not be here."); 19546624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber break; 19556624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 19566624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 1957e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sampleIndex; 19586624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber status_t err = mSampleTable->findSampleAtTime( 1959e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber seekTimeUs * mTimescale / 1000000, 19606624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber &sampleIndex, findFlags); 19616624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 19626624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 19636624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber // We found the closest sample already, now we want the sync 19646624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber // sample preceding it (or the sample itself of course), even 19656624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber // if the subsequent sync sample is closer. 19666624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber findFlags = SampleTable::kFlagBefore; 19676624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 19686624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 19696624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t syncSampleIndex; 19706624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (err == OK) { 19716624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber err = mSampleTable->findSyncSampleNear( 19726624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber sampleIndex, &syncSampleIndex, findFlags); 19736624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 1974e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 197590ba107fcf36ce6df111a594b2cc27163b36793dAndreas Huber uint32_t sampleTime; 197690ba107fcf36ce6df111a594b2cc27163b36793dAndreas Huber if (err == OK) { 197790ba107fcf36ce6df111a594b2cc27163b36793dAndreas Huber err = mSampleTable->getMetaDataForSample( 197890ba107fcf36ce6df111a594b2cc27163b36793dAndreas Huber sampleIndex, NULL, NULL, &sampleTime); 197990ba107fcf36ce6df111a594b2cc27163b36793dAndreas Huber } 198090ba107fcf36ce6df111a594b2cc27163b36793dAndreas Huber 1981e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 1982d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber if (err == ERROR_OUT_OF_RANGE) { 1983d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // An attempt to seek past the end of the stream would 1984d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // normally cause this ERROR_OUT_OF_RANGE error. Propagating 1985d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // this all the way to the MediaPlayer would cause abnormal 1986d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // termination. Legacy behaviour appears to be to behave as if 1987d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber // we had seeked to the end of stream, ending normally. 1988d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber err = ERROR_END_OF_STREAM; 1989d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber } 1990e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 1991e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1992e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 19936624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (mode == ReadOptions::SEEK_CLOSEST) { 19946624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 19956624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 19966624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 19976624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber#if 0 19986624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber uint32_t syncSampleTime; 19996624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 20006624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber syncSampleIndex, NULL, NULL, &syncSampleTime)); 20016624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 20026624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber LOGI("seek to time %lld us => sample at time %lld us, " 20036624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber "sync sample at time %lld us", 20046624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber seekTimeUs, 20056624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber sampleTime * 1000000ll / mTimescale, 20066624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber syncSampleTime * 1000000ll / mTimescale); 20076624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber#endif 20086624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 20096624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber mCurrentSampleIndex = syncSampleIndex; 2010e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 2011e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 2012e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 2013e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2014e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2015e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // fall through 2016e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2017e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2018b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t offset; 20198a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber size_t size; 202044fdac0c62916ddcfac1fe887d867e7ff0cf446fAndreas Huber uint32_t cts; 2021ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber bool isSyncSample; 20224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool newBuffer = false; 20234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer == NULL) { 20244f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber newBuffer = true; 2025e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 20261faa92a1e93f311e86dca483ed7702091137de66Andreas Huber status_t err = 20271faa92a1e93f311e86dca483ed7702091137de66Andreas Huber mSampleTable->getMetaDataForSample( 202844fdac0c62916ddcfac1fe887d867e7ff0cf446fAndreas Huber mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 2029e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 20304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 20314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 20324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 20334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mGroup->acquire_buffer(&mBuffer); 20351faa92a1e93f311e86dca483ed7702091137de66Andreas Huber 20364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 2037940c866c992f122be7aeb92a1b314d7df437d4e2Andreas Huber CHECK(mBuffer == NULL); 20384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 20394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 20408a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber } 2041e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 20424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC || mWantsNALFragments) { 20434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (newBuffer) { 20444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ssize_t num_bytes_read = 20459a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 20464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20474f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (num_bytes_read < (ssize_t)size) { 20484f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 20494f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 20504f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20514f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 20524f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 20534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2054ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 20554f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, size); 20564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->clear(); 2057fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 205844fdac0c62916ddcfac1fe887d867e7ff0cf446fAndreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 20596624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 20606624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (targetSampleTimeUs >= 0) { 20616624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber mBuffer->meta_data()->setInt64( 20626624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber kKeyTargetTime, targetSampleTimeUs); 20636624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 20646624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 2065ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber if (isSyncSample) { 2066ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 2067ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber } 2068ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber 20694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ++mCurrentSampleIndex; 20704f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 20714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC) { 20734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = mBuffer; 20744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 20754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 20774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 20784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Each NAL unit is split up into its constituent fragments and 20804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // each one of them returned in its own buffer. 20814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2082db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 20834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber const uint8_t *src = 20854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 20864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2087db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber size_t nal_size = parseNALSize(src); 2088909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 2089909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber LOGE("incomplete NAL unit."); 2090909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 2091909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer->release(); 2092909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber mBuffer = NULL; 2093909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 2094909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber return ERROR_MALFORMED; 2095909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber } 20964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 20974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber MediaBuffer *clone = mBuffer->clone(); 2098ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(clone != NULL); 2099db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 21004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2101ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber CHECK(mBuffer != NULL); 21024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range( 2103db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 2104db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 21054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 21064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer->range_length() == 0) { 21074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 21084f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 21094f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 21104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 21114f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = clone; 21124f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 21134f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 21144f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } else { 21154f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Whole NAL units are returned but each fragment is prefixed by 21164f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // the start code (0x00 00 00 01). 2117d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang ssize_t num_bytes_read = 0; 2118d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang int32_t drm = 0; 2119d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 2120d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (usesDRM) { 2121d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang num_bytes_read = 2122d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 2123d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } else { 2124d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 2125d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 2126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (num_bytes_read < (ssize_t)size) { 2128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 2129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 2130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 21314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 2132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2134d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (usesDRM) { 2135d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang CHECK(mBuffer != NULL); 2136d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mBuffer->set_range(0, size); 2137db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber 2138d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } else { 2139d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang uint8_t *dstData = (uint8_t *)mBuffer->data(); 2140d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang size_t srcOffset = 0; 2141d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang size_t dstOffset = 0; 2142909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 2143d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang while (srcOffset < size) { 214434d76acc4edb359a8639ddb6ce537b5156deb760James Dong bool isMalFormed = (srcOffset + mNALLengthSize > size); 214534d76acc4edb359a8639ddb6ce537b5156deb760James Dong size_t nalLength = 0; 214634d76acc4edb359a8639ddb6ce537b5156deb760James Dong if (!isMalFormed) { 214734d76acc4edb359a8639ddb6ce537b5156deb760James Dong nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 214834d76acc4edb359a8639ddb6ce537b5156deb760James Dong srcOffset += mNALLengthSize; 214934d76acc4edb359a8639ddb6ce537b5156deb760James Dong isMalFormed = srcOffset + nalLength > size; 215034d76acc4edb359a8639ddb6ce537b5156deb760James Dong } 2151909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber 215234d76acc4edb359a8639ddb6ce537b5156deb760James Dong if (isMalFormed) { 215334d76acc4edb359a8639ddb6ce537b5156deb760James Dong LOGE("Video is malformed"); 2154d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mBuffer->release(); 2155d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mBuffer = NULL; 2156d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang return ERROR_MALFORMED; 2157d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 2158d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang 2159d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang if (nalLength == 0) { 2160d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang continue; 2161d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 21624f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2163d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang CHECK(dstOffset + 4 <= mBuffer->size()); 21644f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2165d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang dstData[dstOffset++] = 0; 2166d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang dstData[dstOffset++] = 0; 2167d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang dstData[dstOffset++] = 0; 2168d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang dstData[dstOffset++] = 1; 2169d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 2170d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang srcOffset += nalLength; 2171d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang dstOffset += nalLength; 2172d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang } 2173d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang CHECK_EQ(srcOffset, size); 2174d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang CHECK(mBuffer != NULL); 2175d5770917a50a828cb4337c2a392b3e4a375624b9Gloria Wang mBuffer->set_range(0, dstOffset); 21764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 21774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 2178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->clear(); 2179fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 218044fdac0c62916ddcfac1fe887d867e7ff0cf446fAndreas Huber kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 21816624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 21826624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber if (targetSampleTimeUs >= 0) { 21836624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber mBuffer->meta_data()->setInt64( 21846624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber kKeyTargetTime, targetSampleTimeUs); 21856624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber } 21866624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber 2187ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber if (isSyncSample) { 2188ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 2189ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber } 2190ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber 2191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++mCurrentSampleIndex; 2192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = mBuffer; 2194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 2195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 2197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 2199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2200f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas HuberMPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 2201f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber const char *mimePrefix) { 2202f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber for (Track *track = mFirstTrack; track != NULL; track = track->next) { 2203f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber const char *mime; 2204f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber if (track->meta != NULL 2205f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber && track->meta->findCString(kKeyMIMEType, &mime) 2206f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 2207f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber return track; 2208f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber } 2209f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber } 2210f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber 2211f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber return NULL; 2212f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber} 2213f80e45a60a93c7bd63a47f5cb23750b69567fc37Andreas Huber 2214261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberstatic bool LegacySniffMPEG4( 2215be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 2216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t header[8]; 2217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 22189a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 2219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < (ssize_t)sizeof(header)) { 2220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 2221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2224e1130662d0455231853e7d6880bb84d8547d7229James Dong || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2225e1130662d0455231853e7d6880bb84d8547d7229James Dong || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 22266bce6d87b3fd98e68fb54328fb4dc8e40cd2c293Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2227dfb8eee5bd1359d8042c1fd2f5143b416c09dfddAndreas Huber || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2228eea1eefeada90ec54488e1742e81e4226fc6ace5Andreas Huber || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 2229e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 2230efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber *confidence = 0.4; 2231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 2233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2235e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 2236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 2237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2238261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) { 2239261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber static const uint32_t kCompatibleBrands[] = { 2240261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('i', 's', 'o', 'm'), 2241261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('i', 's', 'o', '2'), 2242261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('a', 'v', 'c', '1'), 2243261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('3', 'g', 'p', '4'), 2244261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('m', 'p', '4', '1'), 2245261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber FOURCC('m', 'p', '4', '2'), 22465f3586e1ad21b011ff7d70ce26c2e0aa6d44a3ffJames Dong 22475f3586e1ad21b011ff7d70ce26c2e0aa6d44a3ffJames Dong // Won't promise that the following file types can be played. 22485f3586e1ad21b011ff7d70ce26c2e0aa6d44a3ffJames Dong // Just give these file types a chance. 22495f3586e1ad21b011ff7d70ce26c2e0aa6d44a3ffJames Dong FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 22505f3586e1ad21b011ff7d70ce26c2e0aa6d44a3ffJames Dong FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 2251708d908668b4c3d0ac2493dfc06385dfd8693dc9Andreas Huber 2252708d908668b4c3d0ac2493dfc06385dfd8693dc9Andreas Huber FOURCC('3', 'g', '2', 'a'), // 3GPP2 2253708d908668b4c3d0ac2493dfc06385dfd8693dc9Andreas Huber FOURCC('3', 'g', '2', 'b'), 2254261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber }; 2255261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2256261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber for (size_t i = 0; 2257261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 2258261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber ++i) { 2259261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (kCompatibleBrands[i] == fourcc) { 2260261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 2261261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2262261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2263261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2264261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 2265261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber} 2266261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2267261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable 2268261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber// compatible brand is present. 2269261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberstatic bool BetterSniffMPEG4( 2270261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 2271261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber uint8_t header[12]; 2272261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (source->readAt(0, header, 12) != 12 2273261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber || memcmp("ftyp", &header[4], 4)) { 2274261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 2275261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2276261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2277261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber size_t atomSize = U32_AT(&header[0]); 2278261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (atomSize < 16 || (atomSize % 4) != 0) { 2279261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 2280261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2281261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2282261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber bool success = false; 2283261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (isCompatibleBrand(U32_AT(&header[8]))) { 2284261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber success = true; 2285261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } else { 2286261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber size_t numCompatibleBrands = (atomSize - 16) / 4; 2287261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber for (size_t i = 0; i < numCompatibleBrands; ++i) { 2288261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber uint8_t tmp[4]; 2289261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (source->readAt(16 + i * 4, tmp, 4) != 4) { 2290261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 2291261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2292261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2293261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (isCompatibleBrand(U32_AT(&tmp[0]))) { 2294261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber success = true; 2295261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber break; 2296261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2297261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2298261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2299261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2300261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (!success) { 2301261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 2302261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2303261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2304261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 2305efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber *confidence = 0.4f; 2306261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2307261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 2308261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber} 2309261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2310261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huberbool SniffMPEG4( 2311efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 2312efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber sp<AMessage> *) { 2313261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (BetterSniffMPEG4(source, mimeType, confidence)) { 2314261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 2315261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2316261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2317261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber if (LegacySniffMPEG4(source, mimeType, confidence)) { 2318261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 2319261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return true; 2320261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber } 2321261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2322261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber return false; 2323261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber} 2324261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76Andreas Huber 2325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 2326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2327