AVIExtractor.cpp revision c639aad6d8894f57c02e620f52ccf49e51b64866
1f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber/* 2f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * Copyright (C) 2011 The Android Open Source Project 3f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * 4f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * you may not use this file except in compliance with the License. 6f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * You may obtain a copy of the License at 7f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * 8f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * 10f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * See the License for the specific language governing permissions and 14f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber * limitations under the License. 15f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber */ 16f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 17f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber//#define LOG_NDEBUG 0 18f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#define LOG_TAG "AVIExtractor" 19f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <utils/Log.h> 20f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 21c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber#include "include/avc_utils.h" 22f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include "include/AVIExtractor.h" 23f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 24f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <binder/ProcessState.h> 25f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/foundation/hexdump.h> 26f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 27f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/foundation/ADebug.h> 28f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/DataSource.h> 29f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/MediaBuffer.h> 30f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 31f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/MediaDefs.h> 32f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/MediaErrors.h> 33f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/MetaData.h> 34f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber#include <media/stagefright/Utils.h> 35f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 36f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubernamespace android { 37f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 38f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstruct AVIExtractor::AVISource : public MediaSource { 39f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber AVISource(const sp<AVIExtractor> &extractor, size_t trackIndex); 40f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 41f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber virtual status_t start(MetaData *params); 42f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber virtual status_t stop(); 43f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 44f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber virtual sp<MetaData> getFormat(); 45f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 46f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber virtual status_t read( 47f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 48f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 49f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberprotected: 50f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber virtual ~AVISource(); 51f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 52f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberprivate: 53f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<AVIExtractor> mExtractor; 54f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t mTrackIndex; 55f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const AVIExtractor::Track &mTrack; 56f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber MediaBufferGroup *mBufferGroup; 57f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t mSampleIndex; 58f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 59f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(AVISource); 60f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber}; 61f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 62f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber//////////////////////////////////////////////////////////////////////////////// 63f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 64f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::AVISource::AVISource( 65f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const sp<AVIExtractor> &extractor, size_t trackIndex) 66f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber : mExtractor(extractor), 67f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTrackIndex(trackIndex), 68f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTrack(mExtractor->mTracks.itemAt(trackIndex)), 69f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup(NULL) { 70f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 71f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 72f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::AVISource::~AVISource() { 73f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mBufferGroup) { 74f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber stop(); 75f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 76f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 77f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 78f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::AVISource::start(MetaData *params) { 79f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(!mBufferGroup); 80f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 81f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup = new MediaBufferGroup; 82f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 83f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 84f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 85f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mSampleIndex = 0; 86f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 87f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 88f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 89f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 90f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::AVISource::stop() { 91f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(mBufferGroup); 92f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 93f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber delete mBufferGroup; 94f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup = NULL; 95f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 96f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 97f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 98f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 99f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MetaData> AVIExtractor::AVISource::getFormat() { 100f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return mTrack.mMeta; 101f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 102f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 103f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::AVISource::read( 104f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 105f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(mBufferGroup); 106f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 107f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *buffer = NULL; 108f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 109f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber int64_t seekTimeUs; 110f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ReadOptions::SeekMode seekMode; 111f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 112f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber status_t err = 113f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mExtractor->getSampleIndexAtTime( 114f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTrackIndex, seekTimeUs, seekMode, &mSampleIndex); 115f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 116f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 117f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_END_OF_STREAM; 118f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 119f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 120f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 121f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 122f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 123f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 1247de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 125f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber status_t err = mExtractor->getSampleInfo( 1267de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs); 127f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 128f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++mSampleIndex; 129f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 130f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 131f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_END_OF_STREAM; 132f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 133f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 134f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber MediaBuffer *out; 135f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK); 136f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 137f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size); 138f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 139f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 140f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 141f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 142f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 143f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber out->set_range(0, size); 144f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 145f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber out->meta_data()->setInt64(kKeyTime, timeUs); 146f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 147f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (isKey) { 148f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber out->meta_data()->setInt32(kKeyIsSyncFrame, 1); 149f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 150f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 151f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *buffer = out; 152f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 153f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 154f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 155f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 156f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber//////////////////////////////////////////////////////////////////////////////// 157f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 158f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::AVIExtractor(const sp<DataSource> &dataSource) 159f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber : mDataSource(dataSource) { 160f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mInitCheck = parseHeaders(); 161f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 162f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mInitCheck != OK) { 163f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.clear(); 164f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 165f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 166f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 167f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::~AVIExtractor() { 168f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 169f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 170f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersize_t AVIExtractor::countTracks() { 171f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return mTracks.size(); 172f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 173f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 174f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MediaSource> AVIExtractor::getTrack(size_t index) { 175f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return index < mTracks.size() ? new AVISource(this, index) : NULL; 176f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 177f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 178f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MetaData> AVIExtractor::getTrackMetaData( 179f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t index, uint32_t flags) { 180f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL; 181f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 182f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 183f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MetaData> AVIExtractor::getMetaData() { 184f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<MetaData> meta = new MetaData; 185f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 186f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mInitCheck == OK) { 187f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI); 188f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 189f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 190f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return meta; 191f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 192f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 193f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseHeaders() { 194f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.clear(); 195f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mMovieOffset = 0; 196f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mFoundIndex = false; 197f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute = false; 198f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 199f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t res = parseChunk(0ll, -1ll); 200f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 201f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (res < 0) { 202f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return (status_t)res; 203f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 204f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 205f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mMovieOffset == 0ll || !mFoundIndex) { 206f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 207f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 208f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 209f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 210f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 211f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 212f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) { 213f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size >= 0 && size < 8) { 214f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 215f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 216f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 217f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t tmp[12]; 218f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, tmp, 8); 219f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 220f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 8) { 221f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 222f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 223f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 224f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t fourcc = U32_AT(tmp); 225f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkSize = U32LE_AT(&tmp[4]); 226f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 227f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size >= 0 && chunkSize + 8 > size) { 228f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 229f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 230f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 231f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber static const char kPrefix[] = " "; 232f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth]; 233f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 234f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (fourcc == FOURCC('L', 'I', 'S', 'T') 235f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber || fourcc == FOURCC('R', 'I', 'F', 'F')) { 236f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // It's a list of chunks 237f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 238f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size >= 0 && size < 12) { 239f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 240f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 241f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 242f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber n = mDataSource->readAt(offset + 8, &tmp[8], 4); 243f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 244f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 4) { 245f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 246f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 247f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 248f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t subFourcc = U32_AT(&tmp[8]); 249f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 250f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d", 251f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber prefix, 252f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber offset, 253f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(subFourcc >> 24), 254f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((subFourcc >> 16) & 0xff), 255f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((subFourcc >> 8) & 0xff), 256f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(subFourcc & 0xff), 257f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber chunkSize - 4); 258f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 259f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (subFourcc == FOURCC('m', 'o', 'v', 'i')) { 260f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // We're not going to parse this, but will take note of the 261f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // offset. 262f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 263f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mMovieOffset = offset; 264f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 265f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t subOffset = offset + 12; 266f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t subOffsetLimit = subOffset + chunkSize - 4; 267f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (subOffset < subOffsetLimit) { 268f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t res = 269f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1); 270f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 271f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (res < 0) { 272f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return res; 273f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 274f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 275f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber subOffset += res; 276f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 277f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 278f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 279f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'", 280f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber prefix, 281f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber offset, 282f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(fourcc >> 24), 283f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((fourcc >> 16) & 0xff), 284f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((fourcc >> 8) & 0xff), 285f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(fourcc & 0xff)); 286f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 287f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber status_t err = OK; 288f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 289f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (fourcc) { 290f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('s', 't', 'r', 'h'): 291f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 292f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber err = parseStreamHeader(offset + 8, chunkSize); 293f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 294f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 295f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 296f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('s', 't', 'r', 'f'): 297f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 298f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber err = parseStreamFormat(offset + 8, chunkSize); 299f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 300f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 301f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 302f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('i', 'd', 'x', '1'): 303f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 304f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber err = parseIndex(offset + 8, chunkSize); 305f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 306f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 307f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 308f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 309f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 310f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 311f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 312f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 313f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 314f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 315f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 316f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 317f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize & 1) { 318f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++chunkSize; 319f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 320f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 321f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return chunkSize + 8; 322f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 323f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 324f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic const char *GetMIMETypeForHandler(uint32_t handler) { 325f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (handler) { 326f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // Wow... shamelessly copied from 327f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4 328f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 329f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('3', 'I', 'V', '2'): 330f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('3', 'i', 'v', '2'): 331f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('B', 'L', 'Z', '0'): 332f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'I', 'G', 'I'): 333f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'I', 'V', '1'): 334f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('d', 'i', 'v', '1'): 335f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'I', 'V', 'X'): 336f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('d', 'i', 'v', 'x'): 337f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'X', '5', '0'): 338f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('d', 'x', '5', '0'): 339f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'X', 'G', 'M'): 340f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('E', 'M', '4', 'A'): 341f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('E', 'P', 'H', 'V'): 342f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('F', 'M', 'P', '4'): 343f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('f', 'm', 'p', '4'): 344f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('F', 'V', 'F', 'W'): 345f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('H', 'D', 'X', '4'): 346f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('h', 'd', 'x', '4'): 347f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', '4', 'C', 'C'): 348f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', '4', 'S', '2'): 349f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('m', '4', 's', '2'): 350f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', 'P', '4', 'S'): 351f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('m', 'p', '4', 's'): 352f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', 'P', '4', 'V'): 353f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('m', 'p', '4', 'v'): 354f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', 'V', 'X', 'M'): 355f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('R', 'M', 'P', '4'): 356f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('S', 'E', 'D', 'G'): 357f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('S', 'M', 'P', '4'): 358f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('U', 'M', 'P', '4'): 359f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('W', 'V', '1', 'F'): 360f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('X', 'V', 'I', 'D'): 361f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('X', 'v', 'i', 'D'): 362f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('x', 'v', 'i', 'd'): 363f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('X', 'V', 'I', 'X'): 364f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 365f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 366c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber // from http://wiki.multimedia.cx/index.php?title=H264 367c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('a', 'v', 'c', '1'): 368c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('d', 'a', 'v', 'c'): 369c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('x', '2', '6', '4'): 370c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('v', 's', 's', 'h'): 371c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 372c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 373f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 374f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return NULL; 375f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 376f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 377f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 378f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { 379f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size != 56) { 380f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 381f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 382f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 383f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mTracks.size() > 99) { 384f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 385f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 386f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 387f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 388f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 389f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 390f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 391f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 392f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 393f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 394f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 395f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 396f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t type = U32_AT(data); 397f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t handler = U32_AT(&data[4]); 398f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t flags = U32LE_AT(&data[8]); 399f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 400f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<MetaData> meta = new MetaData; 401f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 402f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t rate = U32LE_AT(&data[20]); 403f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t scale = U32LE_AT(&data[24]); 404f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 4057de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber uint32_t sampleSize = U32LE_AT(&data[44]); 4067de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 407f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *mime = NULL; 408f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track::Kind kind = Track::OTHER; 409f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 410f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (type == FOURCC('v', 'i', 'd', 's')) { 411f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mime = GetMIMETypeForHandler(handler); 412f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 413f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mime && strncasecmp(mime, "video/", 6)) { 414f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 415f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 416f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 417c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (mime == NULL) { 418c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber LOGW("Unsupported video format '%c%c%c%c'", 419c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)(handler >> 24), 420c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)((handler >> 16) & 0xff), 421c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)((handler >> 8) & 0xff), 422c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)(handler & 0xff)); 423c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 424c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 425f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber kind = Track::VIDEO; 426f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else if (type == FOURCC('a', 'u', 'd', 's')) { 427f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mime && strncasecmp(mime, "audio/", 6)) { 428f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 429f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 430f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 431f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber kind = Track::AUDIO; 432f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 433f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 434f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mime) { 435f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mime = "application/octet-stream"; 436f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 437f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 438f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber meta->setCString(kKeyMIMEType, mime); 439f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 440f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.push(); 441f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 442f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 443f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta = meta; 444f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mRate = rate; 445f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mScale = scale; 4467de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber track->mBytesPerSample = sampleSize; 447f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mKind = kind; 448f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mNumSyncSamples = 0; 449f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleSize = 0; 450f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleIndex = -1; 451f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMaxSampleSize = 0; 452f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 453f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 454f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 455f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 456f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) { 457f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mTracks.isEmpty()) { 458f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 459f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 460f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 461f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 462f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 463f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mKind == Track::OTHER) { 464f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // We don't support this content, but that's not a parsing error. 465f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 466f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 467f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 468f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isVideo = (track->mKind == Track::VIDEO); 469f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 470f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if ((isVideo && size < 40) || (!isVideo && size < 18)) { 471f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // Expected a BITMAPINFO or WAVEFORMATEX structure, respectively. 472f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 473f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 474f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 475f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 476f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 477f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 478f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 479f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 480f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 481f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 482f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 483f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 484f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (isVideo) { 485f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t width = U32LE_AT(&data[4]); 486f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t height = U32LE_AT(&data[8]); 487f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 488f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyWidth, width); 489f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyHeight, height); 490f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 491f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t format = U16LE_AT(data); 492c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 493f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (format == 0x55) { 494f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 495c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } else { 496c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber LOGW("Unsupported audio format = 0x%04x", format); 497f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 498f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 499f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t numChannels = U16LE_AT(&data[2]); 500f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t sampleRate = U32LE_AT(&data[4]); 501f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 502f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyChannelCount, numChannels); 503f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeySampleRate, sampleRate); 504f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 505f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 506f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 507f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 508f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 509f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber// static 510f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberbool AVIExtractor::IsCorrectChunkType( 511f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) { 512f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkBase = chunkType & 0xffff; 513f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 514f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (kind) { 515f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case Track::VIDEO: 516f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 517f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkBase != FOURCC(0, 0, 'd', 'c') 518f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber && chunkBase != FOURCC(0, 0, 'd', 'b')) { 519f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 520f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 521f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 522f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 523f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 524f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case Track::AUDIO: 525f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 526f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkBase != FOURCC(0, 0, 'w', 'b')) { 527f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 528f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 529f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 530f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 531f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 532f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 533f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 534f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 535f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 536f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex < 0) { 537f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 538f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 539f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 540f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t hi = chunkType >> 24; 541f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 542f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 543f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 544f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 545f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 546f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 547f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex != (10 * (hi - '0') + (lo - '0'))) { 548f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 549f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 550f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 551f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 552f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 553f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 554f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseIndex(off64_t offset, size_t size) { 555f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if ((size % 16) != 0) { 556f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 557f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 558f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 559f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 560f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 561f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 562f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 563f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 564f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 565f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 566f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 567f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 568f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (size > 0) { 569f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkType = U32_AT(data); 570f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 571f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t hi = chunkType >> 24; 572f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 573f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 574f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 575f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 576f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 577f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 578f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex = 10 * (hi - '0') + (lo - '0'); 579f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 580f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 581f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 582f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 583f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 584f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 585f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 586f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!IsCorrectChunkType(-1, track->mKind, chunkType)) { 587f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 588f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 589f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 590f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mKind == Track::OTHER) { 591f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber data += 16; 592f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size -= 16; 593f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber continue; 594f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 595f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 596f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t flags = U32LE_AT(&data[4]); 597f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t offset = U32LE_AT(&data[8]); 598f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkSize = U32LE_AT(&data[12]); 599f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 600f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize > track->mMaxSampleSize) { 601f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMaxSampleSize = chunkSize; 602f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 603f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 604f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mSamples.push(); 605f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 606f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber SampleInfo *info = 607f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber &track->mSamples.editItemAt(track->mSamples.size() - 1); 608f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 609f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber info->mOffset = offset; 610f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber info->mIsKey = (flags & 0x10) != 0; 611f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 612f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info->mIsKey) { 613f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 614f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 615f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) { 616f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize > track->mThumbnailSampleSize) { 617f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleSize = chunkSize; 618f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 619f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleIndex = 620f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mSamples.size() - 1; 621f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 622f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 623f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 624f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++track->mNumSyncSamples; 625f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 626f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 627f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber data += 16; 628f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size -= 16; 629f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 630f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 631f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mTracks.isEmpty()) { 632f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 633f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 634f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 6357de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 6367de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 637f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 638f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 639f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute = !mOffsetsAreAbsolute; 6407de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 641f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 642f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 643f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 644f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 645f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 646f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 647f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("Chunk offsets are %s", 648f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative"); 649f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 650f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 651f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 652f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(i); 653f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 6547de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t durationUs; 6557de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber CHECK_EQ((status_t)OK, 6567de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleTime(i, track->mSamples.size() - 1, &durationUs)); 657f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 658f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("track %d duration = %.2f secs", i, durationUs / 1E6); 659f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 660f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt64(kKeyDuration, durationUs); 661f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize); 662f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 663f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *tmp; 664f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp)); 665f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 666f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber AString mime = tmp; 667f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 668c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 669c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (track->mThumbnailSampleIndex >= 0) { 670c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int64_t thumbnailTimeUs; 671c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK_EQ((status_t)OK, 672c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber getSampleTime(i, track->mThumbnailSampleIndex, 673c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber &thumbnailTimeUs)); 674f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 675c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 676c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 677c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 678c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber status_t err = OK; 679f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 680f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) { 681c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber err = addMPEG4CodecSpecificData(i); 682c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 683c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber err = addH264CodecSpecificData(i); 684c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 685f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 686c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (err != OK) { 687c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return err; 688f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 689f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 6907de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 6917de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber if (track->mBytesPerSample != 0) { 6927de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber // Assume all chunks are the same size for now. 6937de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 6947de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t offset; 6957de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t size; 6967de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber bool isKey; 6977de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t sampleTimeUs; 6987de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber CHECK_EQ((status_t)OK, 6997de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleInfo( 7007de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber i, 0, 7017de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber &offset, &size, &isKey, &sampleTimeUs)); 7027de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 7037de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber track->mRate *= size / track->mBytesPerSample; 7047de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber } 705f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 706f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 707f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mFoundIndex = true; 708f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 709f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 710f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 711f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 712f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic size_t GetSizeWidth(size_t x) { 713f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t n = 1; 714f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (x > 127) { 715f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++n; 716f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber x >>= 7; 717f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 718f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n; 719f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 720f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 721f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) { 722f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (x > 127) { 723f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = (x & 0x7f) | 0x80; 724f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber x >>= 7; 725f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 726f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = x; 727f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return dst; 728f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 729f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 730f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) { 731f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 732f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 733f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 734f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 735f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> csd = new ABuffer(len3); 736f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t *dst = csd->data(); 737f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x03; 738f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, len2 + 3); 739f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; // ES_ID 740f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; 741f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 742f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 743f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x04; 744f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, len1 + 13); 745f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 746f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber for (size_t i = 0; i < 12; ++i) { 747f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; 748f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 749f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 750f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x05; 751f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, config->size()); 752f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber memcpy(dst, config->data(), config->size()); 753f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst += config->size(); 754f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 755f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // hexdump(csd->data(), csd->size()); 756f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 757f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return csd; 758f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 759f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 760f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { 761f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 762f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 763f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 764f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 765f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 7667de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 7677de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber status_t err = 7687de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs); 769f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 770f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 771f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 772f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 773f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 774f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 775f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 776f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 777f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 778f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 779f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 780f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 781f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // Extract everything up to the first VOP start code from the first 782f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // frame's encoded data and use it to construct an ESDS with the 783f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // codec specific data. 784f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 785f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t i = 0; 786f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool found = false; 787f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (i + 3 < buffer->size()) { 788f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) { 789f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber found = true; 790f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 791f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 792f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 793f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++i; 794f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 795f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 796f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!found) { 797f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 798f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 799f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 800f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber buffer->setRange(0, i); 801f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 802f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer); 803f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size()); 804f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 805f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 806f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 807f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 808c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huberstatus_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) { 809c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 810c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 811c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber off64_t offset; 812c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t size; 813c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber bool isKey; 814c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int64_t timeUs; 815c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 816c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber // Extract codec specific data from the first non-empty sample. 817c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 818c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t sampleIndex = 0; 819c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber for (;;) { 820c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber status_t err = 821c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber getSampleInfo( 822c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs); 823c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 824c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (err != OK) { 825c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return err; 826c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 827c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 828c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (size > 0) { 829c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber break; 830c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 831c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 832c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber ++sampleIndex; 833c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 834c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 835c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 836c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 837c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 838c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (n < (ssize_t)size) { 839c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 840c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 841c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 842c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber sp<MetaData> meta = MakeAVCCodecSpecificData(buffer); 843c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 844c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (meta == NULL) { 845c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber LOGE("Unable to extract AVC codec specific data"); 846c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return ERROR_MALFORMED; 847c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 848c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 849c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int32_t width, height; 850c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 851c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 852c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 853c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber uint32_t type; 854c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber const void *csd; 855c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t csdSize; 856c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize)); 857c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 858c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt32(kKeyWidth, width); 859c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt32(kKeyHeight, width); 860c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setData(kKeyAVCC, type, csd, csdSize); 861c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 862c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return OK; 863c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber} 864c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 865f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::getSampleInfo( 866f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex, size_t sampleIndex, 8677de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t *offset, size_t *size, bool *isKey, 8687de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t *sampleTimeUs) { 869f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 870f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 871f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 872f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 873f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const Track &track = mTracks.itemAt(trackIndex); 874f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 875f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (sampleIndex >= track.mSamples.size()) { 876f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 877f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 878f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 879f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = track.mSamples.itemAt(sampleIndex); 880f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 881f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mOffsetsAreAbsolute) { 882f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset = info.mOffset + mMovieOffset + 8; 883f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 884f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset = info.mOffset; 885f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 886f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 887f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *size = 0; 888f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 889f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t tmp[8]; 890f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(*offset, tmp, 8); 891f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 892f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 8) { 893f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 894f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 895f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 896f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkType = U32_AT(tmp); 897f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 898f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) { 899f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 900f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 901f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 902f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset += 8; 903f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *size = U32LE_AT(&tmp[4]); 904f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 905f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *isKey = info.mIsKey; 906f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 9077de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale; 9087de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 909f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 910f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 911f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 9127de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huberstatus_t AVIExtractor::getSampleTime( 9137de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) { 9147de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t offset; 9157de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t size; 9167de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber bool isKey; 9177de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber return getSampleInfo( 9187de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs); 9197de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber} 9207de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 921f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::getSampleIndexAtTime( 922f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex, 923f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode, 924f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t *sampleIndex) const { 925f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 926f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 927f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 928f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 929f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const Track &track = mTracks.itemAt(trackIndex); 930f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 931f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t closestSampleIndex = 932f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber timeUs / track.mRate * track.mScale / 1000000ll; 933f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 934f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t numSamples = track.mSamples.size(); 935f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 936f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (closestSampleIndex < 0) { 937f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber closestSampleIndex = 0; 938f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else if (closestSampleIndex >= numSamples) { 939f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber closestSampleIndex = numSamples - 1; 940f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 941f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 942f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) { 943f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = closestSampleIndex; 944f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 945f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 946f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 947f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 948f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t prevSyncSampleIndex = closestSampleIndex; 949f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (prevSyncSampleIndex >= 0) { 950f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = 951f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track.mSamples.itemAt(prevSyncSampleIndex); 952f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 953f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info.mIsKey) { 954f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 955f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 956f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 957f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber --prevSyncSampleIndex; 958f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 959f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 960f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t nextSyncSampleIndex = closestSampleIndex; 961f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (nextSyncSampleIndex < numSamples) { 962f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = 963f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track.mSamples.itemAt(nextSyncSampleIndex); 964f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 965f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info.mIsKey) { 966f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 967f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 968f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 969f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++nextSyncSampleIndex; 970f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 971f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 972f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (mode) { 973f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 974f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 975f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = prevSyncSampleIndex; 976f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 977f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR; 978f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 979f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 980f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 981f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 982f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = nextSyncSampleIndex; 983f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 984f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR; 985f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 986f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 987f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 988f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 989f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) { 990f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return UNKNOWN_ERROR; 991f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 992f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 993f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (prevSyncSampleIndex < 0) { 994f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = nextSyncSampleIndex; 995f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 996f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 997f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 998f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (nextSyncSampleIndex >= numSamples) { 999f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = prevSyncSampleIndex; 1000f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1001f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1002f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1003f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t dist1 = closestSampleIndex - prevSyncSampleIndex; 1004f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t dist2 = nextSyncSampleIndex - closestSampleIndex; 1005f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1006f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = 1007f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex; 1008f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1009f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1010f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1011f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1012f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 1013f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber TRESPASS(); 1014f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1015f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1016f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1017f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1018f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberbool SniffAVI( 1019f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 1020f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<AMessage> *) { 1021f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber char tmp[12]; 1022f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (source->readAt(0, tmp, 12) < 12) { 1023f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 1024f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1025f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1026f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) { 1027f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI); 1028c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber 1029c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // Just a tad over the mp3 extractor's confidence, since 1030c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // these .avi files may contain .mp3 content that otherwise would 1031c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // mistakenly lead to us identifying the entire file as a .mp3 file. 1032c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber *confidence = 0.21; 1033f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1034f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 1035f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1036f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1037f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 1038f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1039f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1040f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} // namespace android 1041