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