AVIExtractor.cpp revision ec2e74b538b899aac54f55ed1aa60286624f8895
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 4603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("%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 { 4893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("%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'): 580ec2e74b538b899aac54f55ed1aa60286624f8895Dongwon Kang case FOURCC('H', '2', '6', '4'): 581c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber case FOURCC('v', 's', 's', 'h'): 582c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 583c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 584f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 585f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return NULL; 586f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 587f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 588f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 589f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { 590f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (size != 56) { 591f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 592f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 593f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 594f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mTracks.size() > 99) { 595f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 596f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 597f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 598f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 599f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 600f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 601f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 602f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 603f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 604f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 605f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 606f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 607f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t type = U32_AT(data); 608f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t handler = U32_AT(&data[4]); 609f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t flags = U32LE_AT(&data[8]); 610f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 611f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<MetaData> meta = new MetaData; 612f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 613f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t rate = U32LE_AT(&data[20]); 614f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t scale = U32LE_AT(&data[24]); 615f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 6167de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber uint32_t sampleSize = U32LE_AT(&data[44]); 6177de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 618f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *mime = NULL; 619f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track::Kind kind = Track::OTHER; 620f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 621f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (type == FOURCC('v', 'i', 'd', 's')) { 622f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mime = GetMIMETypeForHandler(handler); 623f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 624f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mime && strncasecmp(mime, "video/", 6)) { 625f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 626f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 627f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 628c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (mime == NULL) { 6295ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Unsupported video format '%c%c%c%c'", 630c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)(handler >> 24), 631c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)((handler >> 16) & 0xff), 632c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)((handler >> 8) & 0xff), 633c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber (char)(handler & 0xff)); 634c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 635c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 636f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber kind = Track::VIDEO; 637f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else if (type == FOURCC('a', 'u', 'd', 's')) { 638f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mime && strncasecmp(mime, "audio/", 6)) { 639f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 640f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 641f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 642f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber kind = Track::AUDIO; 643f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 644f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 645f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mime) { 646f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mime = "application/octet-stream"; 647f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 648f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 649f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber meta->setCString(kKeyMIMEType, mime); 650f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 651f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mTracks.push(); 652f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 653f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 654f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta = meta; 655f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mRate = rate; 656f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mScale = scale; 6577de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber track->mBytesPerSample = sampleSize; 658f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mKind = kind; 659f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mNumSyncSamples = 0; 660f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleSize = 0; 661f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleIndex = -1; 662f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMaxSampleSize = 0; 66332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mAvgChunkSize = 1.0; 66432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mFirstChunkSize = 0; 665f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 666f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 667f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 668f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 669f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) { 670f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mTracks.isEmpty()) { 671f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 672f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 673f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 674f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 675f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 676f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mKind == Track::OTHER) { 677f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // We don't support this content, but that's not a parsing error. 678f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 679f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 680f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 681f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isVideo = (track->mKind == Track::VIDEO); 682f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 68332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if ((isVideo && size < 40) || (!isVideo && size < 16)) { 68432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively. 685f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 686f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 687f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 688f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 689f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 690f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 691f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 692f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 693f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 694f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 695f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 696f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 697f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (isVideo) { 698f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t width = U32LE_AT(&data[4]); 699f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t height = U32LE_AT(&data[8]); 700f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 701f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyWidth, width); 702f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyHeight, height); 703f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 704f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t format = U16LE_AT(data); 705c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 706f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (format == 0x55) { 707f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 708c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } else { 7095ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Unsupported audio format = 0x%04x", format); 710f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 711f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 712f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t numChannels = U16LE_AT(&data[2]); 713f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t sampleRate = U32LE_AT(&data[4]); 714f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 715f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyChannelCount, numChannels); 716f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeySampleRate, sampleRate); 717f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 718f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 719f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 720f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 721f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 722f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber// static 723f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberbool AVIExtractor::IsCorrectChunkType( 724f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) { 725f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkBase = chunkType & 0xffff; 726f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 727f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (kind) { 728f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case Track::VIDEO: 729f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 730f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkBase != FOURCC(0, 0, 'd', 'c') 731f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber && chunkBase != FOURCC(0, 0, 'd', 'b')) { 732f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 733f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 734f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 735f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 736f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 737f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case Track::AUDIO: 738f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 739f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkBase != FOURCC(0, 0, 'w', 'b')) { 740f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 741f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 742f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 743f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 744f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 745f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 746f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 747f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 748f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 749f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex < 0) { 750f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 751f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 752f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 753f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t hi = chunkType >> 24; 754f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 755f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 756f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 757f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 758f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 759f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 760f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex != (10 * (hi - '0') + (lo - '0'))) { 761f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 762f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 763f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 764f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 765f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 766f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 767f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::parseIndex(off64_t offset, size_t size) { 768f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if ((size % 16) != 0) { 769f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 770f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 771f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 772f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 773f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 774f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 775f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 776f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 777f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 778f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 779f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const uint8_t *data = buffer->data(); 780f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 781f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (size > 0) { 782f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkType = U32_AT(data); 783f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 784f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t hi = chunkType >> 24; 785f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 786f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 787f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 788f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 789f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 790f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 791f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex = 10 * (hi - '0') + (lo - '0'); 792f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 793f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 794f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 795f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 796f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 797f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 798f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 799f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!IsCorrectChunkType(-1, track->mKind, chunkType)) { 800f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 801f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 802f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 803f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mKind == Track::OTHER) { 804f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber data += 16; 805f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size -= 16; 806f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber continue; 807f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 808f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 809f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t flags = U32LE_AT(&data[4]); 810f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t offset = U32LE_AT(&data[8]); 811f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkSize = U32LE_AT(&data[12]); 812f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 813f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize > track->mMaxSampleSize) { 814f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMaxSampleSize = chunkSize; 815f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 816f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 817f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mSamples.push(); 818f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 819f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber SampleInfo *info = 820f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber &track->mSamples.editItemAt(track->mSamples.size() - 1); 821f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 822f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber info->mOffset = offset; 823f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber info->mIsKey = (flags & 0x10) != 0; 824f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 825f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info->mIsKey) { 826f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 827f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 828f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) { 829f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (chunkSize > track->mThumbnailSampleSize) { 830f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleSize = chunkSize; 831f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 832f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mThumbnailSampleIndex = 833f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mSamples.size() - 1; 834f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 835f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 836f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 837f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++track->mNumSyncSamples; 838f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 839f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 840f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber data += 16; 841f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size -= 16; 842f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 843f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 844f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mTracks.isEmpty()) { 845f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 846f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 847f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 8487de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 8497de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 850f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 851f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 852f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute = !mOffsetsAreAbsolute; 8537de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 854f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 855f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 856f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 857f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 858f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 859f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 8603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Chunk offsets are %s", 861f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative"); 862f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 863f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 864f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 865f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(i); 866f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 86732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (track->mBytesPerSample > 0) { 86832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Assume all chunks are roughly the same size for now. 86932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 87032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Compute the avg. size of the first 128 chunks (if there are 87132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // that many), but exclude the size of the first one, since 87232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // it may be an outlier. 87332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t numSamplesToAverage = track->mSamples.size(); 87432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (numSamplesToAverage > 256) { 87532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber numSamplesToAverage = 256; 87632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 87732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 87832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber double avgChunkSize = 0; 87932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t j; 88032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber for (j = 0; j <= numSamplesToAverage; ++j) { 88132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber off64_t offset; 88232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t size; 88332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber bool isKey; 88432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber int64_t dummy; 88532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 88632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber status_t err = 88732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber getSampleInfo( 88832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber i, j, 88932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber &offset, &size, &isKey, &dummy); 89032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 89132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (err != OK) { 89232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber return err; 89332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 89432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 89532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (j == 0) { 89632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mFirstChunkSize = size; 89732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber continue; 89832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 89932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 90032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber avgChunkSize += size; 90132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 90232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 90332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber avgChunkSize /= numSamplesToAverage; 90432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 90532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track->mAvgChunkSize = avgChunkSize; 90632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 90732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 9087de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t durationUs; 9097de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber CHECK_EQ((status_t)OK, 9107de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleTime(i, track->mSamples.size() - 1, &durationUs)); 911f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 9123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("track %d duration = %.2f secs", i, durationUs / 1E6); 913f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 914f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt64(kKeyDuration, durationUs); 915f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize); 916f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 917f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const char *tmp; 918f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp)); 919f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 920f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber AString mime = tmp; 921f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 922c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 923c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (track->mThumbnailSampleIndex >= 0) { 924c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int64_t thumbnailTimeUs; 925c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK_EQ((status_t)OK, 926c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber getSampleTime(i, track->mThumbnailSampleIndex, 927c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber &thumbnailTimeUs)); 928f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 929c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 930c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 931c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 932c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber status_t err = OK; 933f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 934f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) { 935c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber err = addMPEG4CodecSpecificData(i); 936c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 937c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber err = addH264CodecSpecificData(i); 938c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 939f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 940c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (err != OK) { 941c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return err; 942f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 943f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 944f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 945f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 946f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mFoundIndex = true; 947f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 948f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 949f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 950f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 951f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic size_t GetSizeWidth(size_t x) { 952f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t n = 1; 953f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (x > 127) { 954f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++n; 955f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber x >>= 7; 956f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 957f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n; 958f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 959f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 960f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) { 961f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (x > 127) { 962f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = (x & 0x7f) | 0x80; 963f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber x >>= 7; 964f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 965f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = x; 966f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return dst; 967f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 968f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 969f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Hubersp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) { 970f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 971f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 972f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 973f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 974f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> csd = new ABuffer(len3); 975f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t *dst = csd->data(); 976f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x03; 977f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, len2 + 3); 978f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; // ES_ID 979f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; 980f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 981f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 982f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x04; 983f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, len1 + 13); 984f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 985f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber for (size_t i = 0; i < 12; ++i) { 986f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x00; 987f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 988f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 989f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *dst++ = 0x05; 990f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst = EncodeSize(dst, config->size()); 991f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber memcpy(dst, config->data(), config->size()); 992f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber dst += config->size(); 993f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 994f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // hexdump(csd->data(), csd->size()); 995f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 996f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return csd; 997f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 998f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 999f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { 1000f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 1001f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1002f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber off64_t offset; 1003f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t size; 1004f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool isKey; 10057de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t timeUs; 10067de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber status_t err = 10077de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs); 1008f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1009f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (err != OK) { 1010f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return err; 1011f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1012f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1013f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 1014f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1015f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1016f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < (ssize_t)size) { 1017f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 1018f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1019f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1020f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // Extract everything up to the first VOP start code from the first 1021f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // frame's encoded data and use it to construct an ESDS with the 1022f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber // codec specific data. 1023f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1024f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t i = 0; 1025f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber bool found = false; 1026f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (i + 3 < buffer->size()) { 1027f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) { 1028f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber found = true; 1029f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1030f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1031f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1032f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++i; 1033f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1034f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1035f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!found) { 1036f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 1037f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1038f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1039f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber buffer->setRange(0, i); 1040f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1041f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer); 1042f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size()); 1043f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1044f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1045f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1046f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1047c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huberstatus_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) { 1048c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber Track *track = &mTracks.editItemAt(trackIndex); 1049c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1050c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber off64_t offset; 1051c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t size; 1052c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber bool isKey; 1053c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int64_t timeUs; 1054c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1055c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber // Extract codec specific data from the first non-empty sample. 1056c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1057c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t sampleIndex = 0; 1058c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber for (;;) { 1059c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber status_t err = 1060c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber getSampleInfo( 1061c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs); 1062c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1063c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (err != OK) { 1064c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return err; 1065c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1066c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1067c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (size > 0) { 1068c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber break; 1069c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1070c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1071c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber ++sampleIndex; 1072c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1073c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1074c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 1075c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1076c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1077c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (n < (ssize_t)size) { 1078c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 1079c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1080c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1081c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber sp<MetaData> meta = MakeAVCCodecSpecificData(buffer); 1082c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1083c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber if (meta == NULL) { 108429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unable to extract AVC codec specific data"); 1085c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return ERROR_MALFORMED; 1086c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber } 1087c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1088c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber int32_t width, height; 1089c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 1090c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 1091c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1092c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber uint32_t type; 1093c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber const void *csd; 1094c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber size_t csdSize; 1095c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize)); 1096c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1097c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setInt32(kKeyWidth, width); 10984fe1c6c3988f79fd67c14a1f91e4b1df8a7e806fAndreas Huber track->mMeta->setInt32(kKeyHeight, height); 1099c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber track->mMeta->setData(kKeyAVCC, type, csd, csdSize); 1100c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1101c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber return OK; 1102c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber} 1103c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber 1104f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::getSampleInfo( 1105f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex, size_t sampleIndex, 11067de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t *offset, size_t *size, bool *isKey, 11077de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber int64_t *sampleTimeUs) { 1108f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 1109f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 1110f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1111f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1112f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const Track &track = mTracks.itemAt(trackIndex); 1113f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1114f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (sampleIndex >= track.mSamples.size()) { 1115f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 1116f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1117f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1118f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = track.mSamples.itemAt(sampleIndex); 1119f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1120f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!mOffsetsAreAbsolute) { 1121f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset = info.mOffset + mMovieOffset + 8; 1122f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else { 1123f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset = info.mOffset; 1124f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1125f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1126f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *size = 0; 1127f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1128f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint8_t tmp[8]; 1129f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t n = mDataSource->readAt(*offset, tmp, 8); 1130f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1131f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (n < 8) { 1132f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 1133f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1134f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1135f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber uint32_t chunkType = U32_AT(tmp); 1136f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1137f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) { 1138f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return ERROR_MALFORMED; 1139f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1140f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1141f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *offset += 8; 1142f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *size = U32LE_AT(&tmp[4]); 1143f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1144f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *isKey = info.mIsKey; 1145f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 114632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (track.mBytesPerSample > 0) { 114732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t sampleStartInBytes; 114832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (sampleIndex == 0) { 114932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sampleStartInBytes = 0; 115032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 115132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sampleStartInBytes = 115232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1); 115332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 115432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 115532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber sampleIndex = sampleStartInBytes / track.mBytesPerSample; 115632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 115732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 11587de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale; 11597de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 1160f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1161f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1162f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 11637de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huberstatus_t AVIExtractor::getSampleTime( 11647de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) { 11657de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber off64_t offset; 11667de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber size_t size; 11677de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber bool isKey; 11687de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber return getSampleInfo( 11697de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs); 11707de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber} 11717de73f4eb68f3aa478e19ba05a13bc84296f9894Andreas Huber 1172f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberstatus_t AVIExtractor::getSampleIndexAtTime( 1173f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t trackIndex, 1174f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode, 1175f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t *sampleIndex) const { 1176f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (trackIndex >= mTracks.size()) { 1177f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return -ERANGE; 1178f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1179f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1180f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const Track &track = mTracks.itemAt(trackIndex); 1181f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 118232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber ssize_t closestSampleIndex; 118332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 118432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (track.mBytesPerSample > 0) { 118532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber size_t closestByteOffset = 118632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber (timeUs * track.mBytesPerSample) 118732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber / track.mRate * track.mScale / 1000000ll; 118832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber 118932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber if (closestByteOffset <= track.mFirstChunkSize) { 119032e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber closestSampleIndex = 0; 119132e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 119232e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber closestSampleIndex = 119332e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber (closestByteOffset - track.mFirstChunkSize) 119432e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber / track.mAvgChunkSize; 119532e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 119632e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } else { 119732e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber // Each chunk contains a single sample. 119832e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll; 119932e1832dfac3a6bbcc5c0973ccd0e22de4d1a1acAndreas Huber } 1200f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1201f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t numSamples = track.mSamples.size(); 1202f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1203f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (closestSampleIndex < 0) { 1204f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber closestSampleIndex = 0; 1205f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } else if (closestSampleIndex >= numSamples) { 1206f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber closestSampleIndex = numSamples - 1; 1207f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1208f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1209f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) { 1210f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = closestSampleIndex; 1211f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1212f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1213f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1214f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1215f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t prevSyncSampleIndex = closestSampleIndex; 1216f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (prevSyncSampleIndex >= 0) { 1217f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = 1218f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track.mSamples.itemAt(prevSyncSampleIndex); 1219f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1220f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info.mIsKey) { 1221f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1222f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1223f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1224f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber --prevSyncSampleIndex; 1225f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1226f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1227f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ssize_t nextSyncSampleIndex = closestSampleIndex; 1228f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber while (nextSyncSampleIndex < numSamples) { 1229f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const SampleInfo &info = 1230f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber track.mSamples.itemAt(nextSyncSampleIndex); 1231f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1232f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (info.mIsKey) { 1233f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1234f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1235f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1236f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber ++nextSyncSampleIndex; 1237f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1238f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1239f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber switch (mode) { 1240f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 1241f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 1242f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = prevSyncSampleIndex; 1243f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1244f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR; 1245f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1246f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1247f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 1248f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 1249f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = nextSyncSampleIndex; 1250f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1251f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR; 1252f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1253f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1254f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 1255f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber { 1256f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) { 1257f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return UNKNOWN_ERROR; 1258f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1259f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1260f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (prevSyncSampleIndex < 0) { 1261f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = nextSyncSampleIndex; 1262f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1263f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1264f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1265f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (nextSyncSampleIndex >= numSamples) { 1266f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = prevSyncSampleIndex; 1267f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1268f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1269f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1270f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t dist1 = closestSampleIndex - prevSyncSampleIndex; 1271f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber size_t dist2 = nextSyncSampleIndex - closestSampleIndex; 1272f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1273f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber *sampleIndex = 1274f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex; 1275f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1276f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return OK; 1277f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1278f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1279f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber default: 1280f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber TRESPASS(); 1281f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber break; 1282f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1283f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1284f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1285f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huberbool SniffAVI( 1286f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 1287f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber sp<AMessage> *) { 1288f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber char tmp[12]; 1289f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (source->readAt(0, tmp, 12) < 12) { 1290f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 1291f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1292f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1293f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) { 1294f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI); 1295c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber 1296c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // Just a tad over the mp3 extractor's confidence, since 1297c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // these .avi files may contain .mp3 content that otherwise would 1298c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber // mistakenly lead to us identifying the entire file as a .mp3 file. 1299c6c4572cd35f739bfac2aa439b3664032e03dcd8Andreas Huber *confidence = 0.21; 1300f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1301f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return true; 1302f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber } 1303f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1304f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber return false; 1305f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} 1306f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber 1307f8374dec590223ebdd6959b26d9ba90749dd8328Andreas Huber} // namespace android 1308