AVIExtractor.cpp revision 32e1832dfac3a6bbcc5c0973ccd0e22de4d1a1ac
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 5932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sp<MP3Splitter> mSplitter; 6032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 61f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(AVISource); 62f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber}; 63f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 64f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber//////////////////////////////////////////////////////////////////////////////// 65f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 6632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huberstruct AVIExtractor::MP3Splitter : public RefBase { 6732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber MP3Splitter(); 6832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 6932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber void clear(); 7032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber void append(MediaBuffer *buffer); 7132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber status_t read(MediaBuffer **buffer); 7232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 7332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huberprotected: 7432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber virtual ~MP3Splitter(); 7532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 7632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huberprivate: 7732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber bool mFindSync; 7832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int64_t mBaseTimeUs; 7932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int64_t mNumSamplesRead; 8032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sp<ABuffer> mBuffer; 8132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 8232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber bool resync(); 8332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 8432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(MP3Splitter); 8532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber}; 8632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 8732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber//////////////////////////////////////////////////////////////////////////////// 8832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 89f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::AVISource::AVISource( 90f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const sp<AVIExtractor> &extractor, size_t trackIndex) 91f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber : mExtractor(extractor), 92f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTrackIndex(trackIndex), 93f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTrack(mExtractor->mTracks.itemAt(trackIndex)), 94f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup(NULL) { 95f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 96f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 97f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::AVISource::~AVISource() { 98f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mBufferGroup) { 99f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber stop(); 100f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 101f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 102f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 103f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::AVISource::start(MetaData *params) { 104f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(!mBufferGroup); 105f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 106f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup = new MediaBufferGroup; 107f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 108f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 109f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 110f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mSampleIndex = 0; 111f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 11232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber const char *mime; 11332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber CHECK(mTrack.mMeta->findCString(kKeyMIMEType, &mime)); 11432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 11532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 11632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mSplitter = new MP3Splitter; 11732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 11832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mSplitter.clear(); 11932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 12032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 121f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 122f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 123f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 124f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::AVISource::stop() { 125f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(mBufferGroup); 126f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 127f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber delete mBufferGroup; 128f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mBufferGroup = NULL; 129f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 13032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mSplitter.clear(); 13132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 132f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 133f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 134f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 135f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MetaData> AVIExtractor::AVISource::getFormat() { 136f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return mTrack.mMeta; 137f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 138f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 139f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::AVISource::read( 140f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 141f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(mBufferGroup); 142f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 143f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *buffer = NULL; 144f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 145f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber int64_t seekTimeUs; 146f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ReadOptions::SeekMode seekMode; 147f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 148f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber status_t err = 149f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mExtractor->getSampleIndexAtTime( 150f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTrackIndex, seekTimeUs, seekMode, &mSampleIndex); 151f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 152f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 153f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_END_OF_STREAM; 154f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 15532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 15632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mSplitter != NULL) { 15732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mSplitter->clear(); 15832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 159f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 160f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 16132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber for (;;) { 16232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mSplitter != NULL) { 16332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber status_t err = mSplitter->read(buffer); 164f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 16532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (err == OK) { 16632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber break; 16732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else if (err != -EAGAIN) { 16832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return err; 16932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 17032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 171f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 17232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber off64_t offset; 17332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t size; 17432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber bool isKey; 17532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int64_t timeUs; 17632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber status_t err = mExtractor->getSampleInfo( 17732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs); 17832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 17932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber ++mSampleIndex; 18032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 18132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (err != OK) { 18232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return ERROR_END_OF_STREAM; 18332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 18432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 18532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber MediaBuffer *out; 18632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK); 18732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 18832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size); 18932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 19032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (n < (ssize_t)size) { 19132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 19232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 19332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 19432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber out->set_range(0, size); 19532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 19632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber out->meta_data()->setInt64(kKeyTime, timeUs); 19732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 19832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (isKey) { 19932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber out->meta_data()->setInt32(kKeyIsSyncFrame, 1); 20032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 20132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 20232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mSplitter == NULL) { 20332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber *buffer = out; 20432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber break; 20532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 20632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 20732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mSplitter->append(out); 20832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber out->release(); 20932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber out = NULL; 210f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 211f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 21232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return OK; 21332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber} 214f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 21532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber//////////////////////////////////////////////////////////////////////////////// 216f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 21732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas HuberAVIExtractor::MP3Splitter::MP3Splitter() 21832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber : mFindSync(true), 21932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBaseTimeUs(-1ll), 22032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mNumSamplesRead(0) { 22132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber} 22232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 22332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas HuberAVIExtractor::MP3Splitter::~MP3Splitter() { 22432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber} 22532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 22632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Hubervoid AVIExtractor::MP3Splitter::clear() { 22732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mFindSync = true; 22832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBaseTimeUs = -1ll; 22932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mNumSamplesRead = 0; 23032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 23132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer != NULL) { 23232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->setRange(0, 0); 233f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 23432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber} 235f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 23632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Hubervoid AVIExtractor::MP3Splitter::append(MediaBuffer *buffer) { 23732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t prevCapacity = (mBuffer != NULL) ? mBuffer->capacity() : 0; 238f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 23932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBaseTimeUs < 0) { 24032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber CHECK(mBuffer == NULL || mBuffer->size() == 0); 24132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &mBaseTimeUs)); 24232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mNumSamplesRead = 0; 24332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 244f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 24532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer != NULL && mBuffer->offset() > 0) { 24632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber memmove(mBuffer->base(), mBuffer->data(), mBuffer->size()); 24732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->setRange(0, mBuffer->size()); 248f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 249f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 25032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer == NULL 25132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber || mBuffer->size() + buffer->range_length() > prevCapacity) { 25232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t newCapacity = 25332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber (prevCapacity + buffer->range_length() + 1023) & ~1023; 25432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 25532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sp<ABuffer> newBuffer = new ABuffer(newCapacity); 25632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer != NULL) { 25732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 25832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber newBuffer->setRange(0, mBuffer->size()); 25932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 26032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber newBuffer->setRange(0, 0); 26132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 26232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer = newBuffer; 26332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 26432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 26532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber memcpy(mBuffer->data() + mBuffer->size(), 26632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(), 26732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber buffer->range_length()); 26832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 26932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->setRange(0, mBuffer->size() + buffer->range_length()); 27032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber} 27132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 27232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huberbool AVIExtractor::MP3Splitter::resync() { 27332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer == NULL) { 27432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return false; 27532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 27632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 27732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber bool foundSync = false; 27832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber for (size_t offset = 0; offset + 3 < mBuffer->size(); ++offset) { 27932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber uint32_t firstHeader = U32_AT(mBuffer->data() + offset); 28032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 28132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t frameSize; 28232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (!GetMPEGAudioFrameSize(firstHeader, &frameSize)) { 28332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber continue; 28432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 28532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 28632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t subsequentOffset = offset + frameSize; 28732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t i = 3; 28832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber while (i > 0) { 28932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (subsequentOffset + 3 >= mBuffer->size()) { 29032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber break; 29132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 29232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 29332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber static const uint32_t kMask = 0xfffe0c00; 29432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 29532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber uint32_t header = U32_AT(mBuffer->data() + subsequentOffset); 29632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if ((header & kMask) != (firstHeader & kMask)) { 29732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber break; 29832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 29932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 30032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (!GetMPEGAudioFrameSize(header, &frameSize)) { 30132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber break; 30232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 30332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 30432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber subsequentOffset += frameSize; 30532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber --i; 30632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 30732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 30832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (i == 0) { 30932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber foundSync = true; 31032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber memmove(mBuffer->data(), 31132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->data() + offset, 31232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->size() - offset); 31332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 31432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->setRange(0, mBuffer->size() - offset); 31532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber break; 31632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 31732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 31832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 31932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return foundSync; 32032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber} 32132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 32232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huberstatus_t AVIExtractor::MP3Splitter::read(MediaBuffer **out) { 32332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber *out = NULL; 32432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 32532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mFindSync) { 32632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (!resync()) { 32732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return -EAGAIN; 32832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 32932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 33032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mFindSync = false; 33132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 33232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 33332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer->size() < 4) { 33432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return -EAGAIN; 33532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 33632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 33732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber uint32_t header = U32_AT(mBuffer->data()); 33832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t frameSize; 33932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int sampleRate; 34032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int numSamples; 34132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (!GetMPEGAudioFrameSize( 34232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber header, &frameSize, &sampleRate, NULL, NULL, &numSamples)) { 34332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return ERROR_MALFORMED; 34432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 34532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 34632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (mBuffer->size() < frameSize) { 34732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return -EAGAIN; 34832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 34932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 35032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber MediaBuffer *mbuf = new MediaBuffer(frameSize); 35132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber memcpy(mbuf->data(), mBuffer->data(), frameSize); 35232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 35332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int64_t timeUs = mBaseTimeUs + (mNumSamplesRead * 1000000ll) / sampleRate; 35432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mNumSamplesRead += numSamples; 35532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 35632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 35732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 35832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->setRange( 35932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber mBuffer->offset() + frameSize, mBuffer->size() - frameSize); 36032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 36132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber *out = mbuf; 362f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 363f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 364f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 365f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 366f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber//////////////////////////////////////////////////////////////////////////////// 367f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 368f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::AVIExtractor(const sp<DataSource> &dataSource) 369f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber : mDataSource(dataSource) { 370f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mInitCheck = parseHeaders(); 371f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 372f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mInitCheck != OK) { 373f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.clear(); 374f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 375f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 376f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 377f8374dec590223ebdd6959b26d9ba90749dd8328Andreas HuberAVIExtractor::~AVIExtractor() { 378f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 379f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 380f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersize_t AVIExtractor::countTracks() { 381f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return mTracks.size(); 382f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 383f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 384f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MediaSource> AVIExtractor::getTrack(size_t index) { 385f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return index < mTracks.size() ? new AVISource(this, index) : NULL; 386f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 387f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 388f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MetaData> AVIExtractor::getTrackMetaData( 389f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t index, uint32_t flags) { 390f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL; 391f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 392f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 393f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<MetaData> AVIExtractor::getMetaData() { 394f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<MetaData> meta = new MetaData; 395f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 396f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mInitCheck == OK) { 397f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI); 398f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 399f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 400f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return meta; 401f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 402f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 403f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseHeaders() { 404f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.clear(); 405f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mMovieOffset = 0; 406f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mFoundIndex = false; 407f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute = false; 408f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 409f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t res = parseChunk(0ll, -1ll); 410f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 411f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (res < 0) { 412f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return (status_t)res; 413f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 414f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 415f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mMovieOffset == 0ll || !mFoundIndex) { 416f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 417f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 418f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 419f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 420f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 421f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 422f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) { 423f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size >= 0 && size < 8) { 424f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 425f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 426f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 427f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t tmp[12]; 428f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, tmp, 8); 429f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 430f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 8) { 431f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 432f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 433f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 434f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t fourcc = U32_AT(tmp); 435f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkSize = U32LE_AT(&tmp[4]); 436f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 437f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size >= 0 && chunkSize + 8 > size) { 438f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 439f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 440f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 441f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber static const char kPrefix[] = " "; 442f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth]; 443f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 444f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (fourcc == FOURCC('L', 'I', 'S', 'T') 445f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber || fourcc == FOURCC('R', 'I', 'F', 'F')) { 446f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // It's a list of chunks 447f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 448f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size >= 0 && size < 12) { 449f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 450f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 451f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 452f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber n = mDataSource->readAt(offset + 8, &tmp[8], 4); 453f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 454f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 4) { 455f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 456f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 457f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 458f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t subFourcc = U32_AT(&tmp[8]); 459f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 460f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d", 461f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber prefix, 462f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber offset, 463f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(subFourcc >> 24), 464f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((subFourcc >> 16) & 0xff), 465f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((subFourcc >> 8) & 0xff), 466f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(subFourcc & 0xff), 467f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber chunkSize - 4); 468f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 469f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (subFourcc == FOURCC('m', 'o', 'v', 'i')) { 470f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // We're not going to parse this, but will take note of the 471f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // offset. 472f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 473f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mMovieOffset = offset; 474f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 475f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t subOffset = offset + 12; 476f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t subOffsetLimit = subOffset + chunkSize - 4; 477f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (subOffset < subOffsetLimit) { 478f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t res = 479f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1); 480f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 481f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (res < 0) { 482f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return res; 483f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 484f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 485f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber subOffset += res; 486f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 487f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 488f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 489f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'", 490f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber prefix, 491f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber offset, 492f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(fourcc >> 24), 493f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((fourcc >> 16) & 0xff), 494f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)((fourcc >> 8) & 0xff), 495f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (char)(fourcc & 0xff)); 496f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 497f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber status_t err = OK; 498f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 499f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (fourcc) { 500f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('s', 't', 'r', 'h'): 501f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 502f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber err = parseStreamHeader(offset + 8, chunkSize); 503f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 504f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 505f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 506f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('s', 't', 'r', 'f'): 507f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 508f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber err = parseStreamFormat(offset + 8, chunkSize); 509f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 510f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 511f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 512f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('i', 'd', 'x', '1'): 513f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 514f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber err = parseIndex(offset + 8, chunkSize); 515f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 516f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 517f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 518f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 519f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 520f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 521f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 522f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 523f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 524f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 525f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 526f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 527f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize & 1) { 528f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++chunkSize; 529f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 530f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 531f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return chunkSize + 8; 532f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 533f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 534f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic const char *GetMIMETypeForHandler(uint32_t handler) { 535f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (handler) { 536f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // Wow... shamelessly copied from 537f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4 538f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 539f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('3', 'I', 'V', '2'): 540f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('3', 'i', 'v', '2'): 541f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('B', 'L', 'Z', '0'): 542f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'I', 'G', 'I'): 543f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'I', 'V', '1'): 544f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('d', 'i', 'v', '1'): 545f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'I', 'V', 'X'): 546f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('d', 'i', 'v', 'x'): 547f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'X', '5', '0'): 548f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('d', 'x', '5', '0'): 549f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('D', 'X', 'G', 'M'): 550f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('E', 'M', '4', 'A'): 551f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('E', 'P', 'H', 'V'): 552f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('F', 'M', 'P', '4'): 553f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('f', 'm', 'p', '4'): 554f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('F', 'V', 'F', 'W'): 555f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('H', 'D', 'X', '4'): 556f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('h', 'd', 'x', '4'): 557f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', '4', 'C', 'C'): 558f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', '4', 'S', '2'): 559f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('m', '4', 's', '2'): 560f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', 'P', '4', 'S'): 561f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('m', 'p', '4', 's'): 562f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', 'P', '4', 'V'): 563f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('m', 'p', '4', 'v'): 564f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('M', 'V', 'X', 'M'): 565f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('R', 'M', 'P', '4'): 566f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('S', 'E', 'D', 'G'): 567f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('S', 'M', 'P', '4'): 568f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('U', 'M', 'P', '4'): 569f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('W', 'V', '1', 'F'): 570f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('X', 'V', 'I', 'D'): 571f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('X', 'v', 'i', 'D'): 572f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('x', 'v', 'i', 'd'): 573f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case FOURCC('X', 'V', 'I', 'X'): 574f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 575f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 576c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber // from http://wiki.multimedia.cx/index.php?title=H264 577c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('a', 'v', 'c', '1'): 578c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('d', 'a', 'v', 'c'): 579c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('x', '2', '6', '4'): 580c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('v', 's', 's', 'h'): 581c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 582c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 583f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 584f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return NULL; 585f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 586f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 587f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 588f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { 589f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size != 56) { 590f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 591f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 592f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 593f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mTracks.size() > 99) { 594f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 595f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 596f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 597f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 598f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 599f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 600f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 601f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 602f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 603f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 604f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 605f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 606f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t type = U32_AT(data); 607f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t handler = U32_AT(&data[4]); 608f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t flags = U32LE_AT(&data[8]); 609f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 610f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<MetaData> meta = new MetaData; 611f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 612f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t rate = U32LE_AT(&data[20]); 613f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t scale = U32LE_AT(&data[24]); 614f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 6157de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber uint32_t sampleSize = U32LE_AT(&data[44]); 6167de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 617f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *mime = NULL; 618f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track::Kind kind = Track::OTHER; 619f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 620f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (type == FOURCC('v', 'i', 'd', 's')) { 621f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mime = GetMIMETypeForHandler(handler); 622f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 623f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mime && strncasecmp(mime, "video/", 6)) { 624f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 625f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 626f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 627c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (mime == NULL) { 628c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber LOGW("Unsupported video format '%c%c%c%c'", 629c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)(handler >> 24), 630c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)((handler >> 16) & 0xff), 631c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)((handler >> 8) & 0xff), 632c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)(handler & 0xff)); 633c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 634c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 635f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber kind = Track::VIDEO; 636f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else if (type == FOURCC('a', 'u', 'd', 's')) { 637f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mime && strncasecmp(mime, "audio/", 6)) { 638f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 639f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 640f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 641f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber kind = Track::AUDIO; 642f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 643f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 644f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mime) { 645f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mime = "application/octet-stream"; 646f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 647f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 648f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber meta->setCString(kKeyMIMEType, mime); 649f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 650f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.push(); 651f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 652f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 653f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta = meta; 654f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mRate = rate; 655f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mScale = scale; 6567de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber track->mBytesPerSample = sampleSize; 657f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mKind = kind; 658f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mNumSyncSamples = 0; 659f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleSize = 0; 660f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleIndex = -1; 661f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMaxSampleSize = 0; 66232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mAvgChunkSize = 1.0; 66332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mFirstChunkSize = 0; 664f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 665f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 666f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 667f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 668f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) { 669f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mTracks.isEmpty()) { 670f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 671f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 672f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 673f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 674f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 675f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mKind == Track::OTHER) { 676f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // We don't support this content, but that's not a parsing error. 677f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 678f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 679f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 680f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isVideo = (track->mKind == Track::VIDEO); 681f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 68232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if ((isVideo && size < 40) || (!isVideo && size < 16)) { 68332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively. 684f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 685f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 686f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 687f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 688f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 689f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 690f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 691f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 692f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 693f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 694f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 695f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 696f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (isVideo) { 697f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t width = U32LE_AT(&data[4]); 698f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t height = U32LE_AT(&data[8]); 699f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 700f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyWidth, width); 701f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyHeight, height); 702f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 703f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t format = U16LE_AT(data); 704c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 705f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (format == 0x55) { 706f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 707c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } else { 708c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber LOGW("Unsupported audio format = 0x%04x", format); 709f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 710f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 711f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t numChannels = U16LE_AT(&data[2]); 712f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t sampleRate = U32LE_AT(&data[4]); 713f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 714f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyChannelCount, numChannels); 715f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeySampleRate, sampleRate); 716f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 717f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 718f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 719f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 720f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 721f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber// static 722f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberbool AVIExtractor::IsCorrectChunkType( 723f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) { 724f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkBase = chunkType & 0xffff; 725f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 726f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (kind) { 727f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case Track::VIDEO: 728f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 729f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkBase != FOURCC(0, 0, 'd', 'c') 730f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber && chunkBase != FOURCC(0, 0, 'd', 'b')) { 731f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 732f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 733f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 734f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 735f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 736f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case Track::AUDIO: 737f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 738f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkBase != FOURCC(0, 0, 'w', 'b')) { 739f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 740f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 741f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 742f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 743f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 744f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 745f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 746f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 747f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 748f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex < 0) { 749f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 750f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 751f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 752f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t hi = chunkType >> 24; 753f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 754f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 755f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 756f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 757f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 758f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 759f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex != (10 * (hi - '0') + (lo - '0'))) { 760f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 761f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 762f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 763f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 764f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 765f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 766f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseIndex(off64_t offset, size_t size) { 767f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if ((size % 16) != 0) { 768f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 769f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 770f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 771f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 772f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 773f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 774f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 775f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 776f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 777f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 778f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 779f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 780f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (size > 0) { 781f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkType = U32_AT(data); 782f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 783f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t hi = chunkType >> 24; 784f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 785f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 786f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 787f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 788f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 789f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 790f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex = 10 * (hi - '0') + (lo - '0'); 791f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 792f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 793f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 794f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 795f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 796f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 797f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 798f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!IsCorrectChunkType(-1, track->mKind, chunkType)) { 799f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 800f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 801f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 802f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mKind == Track::OTHER) { 803f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber data += 16; 804f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size -= 16; 805f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber continue; 806f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 807f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 808f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t flags = U32LE_AT(&data[4]); 809f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t offset = U32LE_AT(&data[8]); 810f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkSize = U32LE_AT(&data[12]); 811f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 812f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize > track->mMaxSampleSize) { 813f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMaxSampleSize = chunkSize; 814f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 815f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 816f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mSamples.push(); 817f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 818f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber SampleInfo *info = 819f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber &track->mSamples.editItemAt(track->mSamples.size() - 1); 820f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 821f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber info->mOffset = offset; 822f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber info->mIsKey = (flags & 0x10) != 0; 823f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 824f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info->mIsKey) { 825f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 826f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 827f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) { 828f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize > track->mThumbnailSampleSize) { 829f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleSize = chunkSize; 830f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 831f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleIndex = 832f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mSamples.size() - 1; 833f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 834f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 835f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 836f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++track->mNumSyncSamples; 837f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 838f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 839f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber data += 16; 840f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size -= 16; 841f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 842f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 843f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mTracks.isEmpty()) { 844f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 845f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 846f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 8477de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 8487de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 849f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 850f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 851f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute = !mOffsetsAreAbsolute; 8527de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 853f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 854f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 855f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 856f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 857f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 858f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 859f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("Chunk offsets are %s", 860f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative"); 861f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 862f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 863f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 864f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(i); 865f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 86632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (track->mBytesPerSample > 0) { 86732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Assume all chunks are roughly the same size for now. 86832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 86932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Compute the avg. size of the first 128 chunks (if there are 87032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // that many), but exclude the size of the first one, since 87132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // it may be an outlier. 87232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t numSamplesToAverage = track->mSamples.size(); 87332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (numSamplesToAverage > 256) { 87432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber numSamplesToAverage = 256; 87532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 87632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 87732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber double avgChunkSize = 0; 87832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t j; 87932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber for (j = 0; j <= numSamplesToAverage; ++j) { 88032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber off64_t offset; 88132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t size; 88232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber bool isKey; 88332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int64_t dummy; 88432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 88532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber status_t err = 88632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber getSampleInfo( 88732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber i, j, 88832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber &offset, &size, &isKey, &dummy); 88932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 89032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (err != OK) { 89132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return err; 89232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 89332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 89432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (j == 0) { 89532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mFirstChunkSize = size; 89632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber continue; 89732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 89832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 89932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber avgChunkSize += size; 90032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 90132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 90232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber avgChunkSize /= numSamplesToAverage; 90332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 90432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mAvgChunkSize = avgChunkSize; 90532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 90632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 9077de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t durationUs; 9087de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber CHECK_EQ((status_t)OK, 9097de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleTime(i, track->mSamples.size() - 1, &durationUs)); 910f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 911f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber LOGV("track %d duration = %.2f secs", i, durationUs / 1E6); 912f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 913f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt64(kKeyDuration, durationUs); 914f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize); 915f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 916f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *tmp; 917f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp)); 918f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 919f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber AString mime = tmp; 920f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 921c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 922c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (track->mThumbnailSampleIndex >= 0) { 923c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int64_t thumbnailTimeUs; 924c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK_EQ((status_t)OK, 925c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber getSampleTime(i, track->mThumbnailSampleIndex, 926c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber &thumbnailTimeUs)); 927f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 928c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 929c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 930c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 931c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber status_t err = OK; 932f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 933f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) { 934c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber err = addMPEG4CodecSpecificData(i); 935c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 936c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber err = addH264CodecSpecificData(i); 937c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 938f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 939c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (err != OK) { 940c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return err; 941f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 942f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 943f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 944f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 945f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mFoundIndex = true; 946f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 947f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 948f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 949f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 950f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic size_t GetSizeWidth(size_t x) { 951f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t n = 1; 952f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (x > 127) { 953f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++n; 954f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber x >>= 7; 955f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 956f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n; 957f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 958f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 959f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) { 960f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (x > 127) { 961f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = (x & 0x7f) | 0x80; 962f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber x >>= 7; 963f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 964f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = x; 965f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return dst; 966f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 967f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 968f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) { 969f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 970f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 971f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 972f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 973f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> csd = new ABuffer(len3); 974f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t *dst = csd->data(); 975f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x03; 976f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, len2 + 3); 977f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; // ES_ID 978f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; 979f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 980f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 981f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x04; 982f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, len1 + 13); 983f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 984f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber for (size_t i = 0; i < 12; ++i) { 985f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; 986f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 987f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 988f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x05; 989f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, config->size()); 990f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber memcpy(dst, config->data(), config->size()); 991f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst += config->size(); 992f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 993f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // hexdump(csd->data(), csd->size()); 994f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 995f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return csd; 996f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 997f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 998f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { 999f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 1000f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1001f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 1002f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 1003f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 10047de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 10057de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber status_t err = 10067de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs); 1007f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1008f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 1009f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 1010f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1011f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1012f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 1013f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1014f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1015f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 1016f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 1017f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1018f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1019f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // Extract everything up to the first VOP start code from the first 1020f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // frame's encoded data and use it to construct an ESDS with the 1021f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // codec specific data. 1022f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1023f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t i = 0; 1024f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool found = false; 1025f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (i + 3 < buffer->size()) { 1026f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) { 1027f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber found = true; 1028f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1029f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1030f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1031f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++i; 1032f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1033f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1034f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!found) { 1035f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 1036f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1037f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1038f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber buffer->setRange(0, i); 1039f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1040f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer); 1041f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size()); 1042f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1043f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1044f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1045f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1046c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huberstatus_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) { 1047c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 1048c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1049c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber off64_t offset; 1050c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t size; 1051c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber bool isKey; 1052c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int64_t timeUs; 1053c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1054c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber // Extract codec specific data from the first non-empty sample. 1055c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1056c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t sampleIndex = 0; 1057c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber for (;;) { 1058c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber status_t err = 1059c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber getSampleInfo( 1060c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs); 1061c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1062c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (err != OK) { 1063c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return err; 1064c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1065c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1066c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (size > 0) { 1067c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber break; 1068c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1069c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1070c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber ++sampleIndex; 1071c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1072c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1073c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 1074c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1075c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1076c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (n < (ssize_t)size) { 1077c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 1078c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1079c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1080c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber sp<MetaData> meta = MakeAVCCodecSpecificData(buffer); 1081c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1082c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (meta == NULL) { 1083c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber LOGE("Unable to extract AVC codec specific data"); 1084c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return ERROR_MALFORMED; 1085c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1086c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1087c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int32_t width, height; 1088c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 1089c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 1090c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1091c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber uint32_t type; 1092c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber const void *csd; 1093c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t csdSize; 1094c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize)); 1095c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1096c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt32(kKeyWidth, width); 1097c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt32(kKeyHeight, width); 1098c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setData(kKeyAVCC, type, csd, csdSize); 1099c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1100c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return OK; 1101c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber} 1102c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1103f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::getSampleInfo( 1104f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex, size_t sampleIndex, 11057de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t *offset, size_t *size, bool *isKey, 11067de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t *sampleTimeUs) { 1107f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 1108f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 1109f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1110f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1111f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const Track &track = mTracks.itemAt(trackIndex); 1112f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1113f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (sampleIndex >= track.mSamples.size()) { 1114f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 1115f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1116f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1117f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = track.mSamples.itemAt(sampleIndex); 1118f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1119f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mOffsetsAreAbsolute) { 1120f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset = info.mOffset + mMovieOffset + 8; 1121f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 1122f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset = info.mOffset; 1123f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1124f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1125f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *size = 0; 1126f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1127f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t tmp[8]; 1128f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(*offset, tmp, 8); 1129f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1130f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 8) { 1131f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 1132f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1133f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1134f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkType = U32_AT(tmp); 1135f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1136f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) { 1137f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 1138f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1139f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1140f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset += 8; 1141f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *size = U32LE_AT(&tmp[4]); 1142f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1143f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *isKey = info.mIsKey; 1144f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 114532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (track.mBytesPerSample > 0) { 114632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t sampleStartInBytes; 114732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (sampleIndex == 0) { 114832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sampleStartInBytes = 0; 114932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 115032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sampleStartInBytes = 115132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1); 115232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 115332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 115432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sampleIndex = sampleStartInBytes / track.mBytesPerSample; 115532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 115632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 11577de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale; 11587de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 1159f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1160f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1161f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 11627de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huberstatus_t AVIExtractor::getSampleTime( 11637de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) { 11647de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t offset; 11657de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t size; 11667de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber bool isKey; 11677de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber return getSampleInfo( 11687de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs); 11697de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber} 11707de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 1171f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::getSampleIndexAtTime( 1172f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex, 1173f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode, 1174f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t *sampleIndex) const { 1175f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 1176f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 1177f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1178f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1179f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const Track &track = mTracks.itemAt(trackIndex); 1180f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 118132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber ssize_t closestSampleIndex; 118232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 118332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (track.mBytesPerSample > 0) { 118432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t closestByteOffset = 118532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber (timeUs * track.mBytesPerSample) 118632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber / track.mRate * track.mScale / 1000000ll; 118732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 118832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (closestByteOffset <= track.mFirstChunkSize) { 118932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber closestSampleIndex = 0; 119032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 119132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber closestSampleIndex = 119232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber (closestByteOffset - track.mFirstChunkSize) 119332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber / track.mAvgChunkSize; 119432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 119532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 119632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Each chunk contains a single sample. 119732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll; 119832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 1199f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1200f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t numSamples = track.mSamples.size(); 1201f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1202f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (closestSampleIndex < 0) { 1203f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber closestSampleIndex = 0; 1204f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else if (closestSampleIndex >= numSamples) { 1205f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber closestSampleIndex = numSamples - 1; 1206f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1207f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1208f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) { 1209f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = closestSampleIndex; 1210f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1211f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1212f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1213f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1214f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t prevSyncSampleIndex = closestSampleIndex; 1215f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (prevSyncSampleIndex >= 0) { 1216f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = 1217f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track.mSamples.itemAt(prevSyncSampleIndex); 1218f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1219f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info.mIsKey) { 1220f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1221f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1222f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1223f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber --prevSyncSampleIndex; 1224f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1225f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1226f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t nextSyncSampleIndex = closestSampleIndex; 1227f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (nextSyncSampleIndex < numSamples) { 1228f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = 1229f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track.mSamples.itemAt(nextSyncSampleIndex); 1230f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1231f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info.mIsKey) { 1232f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1233f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1234f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1235f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++nextSyncSampleIndex; 1236f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1237f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1238f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (mode) { 1239f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 1240f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 1241f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = prevSyncSampleIndex; 1242f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1243f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR; 1244f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1245f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1246f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 1247f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 1248f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = nextSyncSampleIndex; 1249f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1250f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR; 1251f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1252f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1253f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 1254f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 1255f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) { 1256f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return UNKNOWN_ERROR; 1257f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1258f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1259f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (prevSyncSampleIndex < 0) { 1260f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = nextSyncSampleIndex; 1261f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1262f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1263f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1264f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (nextSyncSampleIndex >= numSamples) { 1265f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = prevSyncSampleIndex; 1266f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1267f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1268f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1269f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t dist1 = closestSampleIndex - prevSyncSampleIndex; 1270f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t dist2 = nextSyncSampleIndex - closestSampleIndex; 1271f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1272f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = 1273f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex; 1274f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1275f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1276f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1277f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1278f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 1279f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber TRESPASS(); 1280f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1281f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1282f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1283f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1284f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberbool SniffAVI( 1285f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 1286f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<AMessage> *) { 1287f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber char tmp[12]; 1288f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (source->readAt(0, tmp, 12) < 12) { 1289f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 1290f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1291f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1292f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) { 1293f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI); 1294c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber 1295c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // Just a tad over the mp3 extractor's confidence, since 1296c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // these .avi files may contain .mp3 content that otherwise would 1297c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // mistakenly lead to us identifying the entire file as a .mp3 file. 1298c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber *confidence = 0.21; 1299f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1300f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 1301f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1302f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1303f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 1304f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1305f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1306f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} // namespace android 1307